combine fuse and rpc for remote directory listing - c

I'm developing a custom file system with fuse. What I want to do is to read contents of a directory from remote server and list them in mount point. My rpc program run solely well. but when I try to combine it with rpc it got some build error. I'm using rpcgen to create my rpc program but I don't know how exactly I should build them together.
this is my cfs_client.c :
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos#szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
gcc -Wall cfs.c `pkg-config fuse --cflags --libs` -o cfs
*/
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "cfs.h"
static const char *cfs_str = "Hello World!\n";
static const char *cfs_path = "/cfs";
static int cfs_getattr(const char *path, struct stat *stbuf) {
int res = 0;
memset(stbuf, 0, sizeof (struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, cfs_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(cfs_str);
} else
res = -ENOENT;
return res;
}
static int cfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) {
(void) offset;
(void) fi;
char *host = "localhost";
char *dirname = "/home/hamed/test";
CLIENT *clnt;
readdir_res *result_1;
if (strcmp(path, "/") != 0)
return -ENOENT;
#ifndef DEBUG
clnt = clnt_create(host, CFSPROG, CFSVERS, "udp");
if (clnt == NULL) {
clnt_pcreateerror(host);
exit(1);
}
#endif /* DEBUG */
result_1 = readdir_1(&dirname, clnt);
if (result_1 == (readdir_res *) NULL) {
clnt_perror(clnt, "call failed");
}
namelist nl;
nl = result_1->readdir_res_u.list;
while (nl) {
printf("dirname = %s\n", nl->name);
filler(buf, nl->name, NULL, 0);
nl = nl->next;
}
#ifndef DEBUG
clnt_destroy(clnt);
#endif /* DEBUG */
return 0;
}
static int cfs_open(const char *path, struct fuse_file_info *fi) {
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int cfs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
size_t len;
(void) fi;
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
len = strlen(cfs_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, cfs_str + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations cfs_oper = {
.getattr = cfs_getattr,
.readdir = cfs_readdir,
.open = cfs_open,
.read = cfs_read,
};
int main(int argc, char *argv[]) {
return fuse_main(argc, argv, &cfs_oper, NULL);
}
here is my cfs_server.c :
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "cfs.h"
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <rpc/pmap_clnt.h>
readdir_res * readdir_1_svc(nametype *dirname, struct svc_req *rqstp) {
DIR *dp;
struct dirent *directory;
static readdir_res result;
int inode;
namelist nl;
namelist *nlp;
dp = opendir(*dirname);
if (dp != NULL) {
nlp = &result.readdir_res_u.list;
while (directory = readdir(dp)) {
nl = *nlp = (namenode *) malloc(sizeof (namenode));
nl->name = directory->d_name;
nlp = &nl->next;
}
}
*nlp = NULL;
result.errnum = 0;
closedir(dp);
return &result;
}
and this is make file that I useed :
# This is a template Makefile generated by rpcgen
# Parameters
CLIENT = cfs_client
SERVER = cfs_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = cfs.x
TARGETS_SVC.c = cfs_svc.c cfs_server.c cfs_xdr.c
TARGETS_CLNT.c = cfs_clnt.c cfs_client.c cfs_xdr.c
TARGETS = cfs.h cfs_xdr.c cfs_clnt.c cfs_svc.c cfs_client.c cfs_server.c
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags
CFLAGS += -g -Wall -DRPC_SVC_FG $(shell pkg-config fuse --cflags --libs)
LDLIBS += -lnsl
RPCGENFLAGS = -g
# Targets
all : $(CLIENT) $(SERVER)
$(TARGETS) : $(SOURCES.x)
rpcgen $(RPCGENFLAGS) $(SOURCES.x)
$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)
$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)
$(CLIENT) : $(OBJECTS_CLNT)
$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
$(SERVER) : $(OBJECTS_SVC)
$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
clean:
$(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)
edit :
error is :
root#debian:/programs/c/rpc/custom file system# make -f Makefile.cfs
rpcgen -g cfs.x
usage: rpcgen infile
rpcgen [-abkCLNTM][-Dname[=value]] [-i size] [-I [-K seconds]] [-Y path] infile
rpcgen [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] [-o outfile] [infile]
rpcgen [-s nettype]* [-o outfile] [infile]
rpcgen [-n netid]* [-o outfile] [infile]
options:
-a generate all files, including samples
-b backward compatibility mode (generates code for SunOS 4.1)
-c generate XDR routines
-C ANSI C mode
-Dname[=value] define a symbol (same as #define)
-h generate header file
-i size size at which to start generating inline code
-I generate code for inetd support in server (for SunOS 4.1)
-K seconds server exits after K seconds of inactivity
-l generate client side stubs
-L server errors will be printed to syslog
-m generate server side stubs
-M generate MT-safe code
-n netid generate server code that supports named netid
-N supports multiple arguments and call-by-value
-o outfile name of the output file
-s nettype generate server code that supports named nettype
-Sc generate sample client code that uses remote procedures
-Ss generate sample server code that defines remote procedures
-Sm generate makefile template
-t generate RPC dispatch table
-T generate code to support RPC dispatch tables
-Y path directory name to find C preprocessor (cpp)
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
make: *** [cfs_clnt.c] Error 1

I've solved my problem by using a bash file. This is my script for those who may have same problem as mine :
cc -g -c -o cfs_clnt.o cfs_clnt.c
cc -g -D_FILE_OFFSET_BITS=64 -c -o cfs_client.o cfs_client.c
cc -g -c -o cfs_xdr.o cfs_xdr.c
cc -g -o cfs_client cfs_clnt.o cfs_client.o cfs_xdr.o -lnsl -Wall `pkg-config fuse --cflags --libs`
cc -g -c -o cfs_svc.o cfs_svc.c
cc -g -c -o cfs_server.o cfs_server.c
cc -g -o cfs_server cfs_svc.o cfs_server.o cfs_xdr.o -lnsl

Related

how to use libmodbus, using a makefile?

Im working in a new project, and i need use modbus tcp/ip... the current project has already a makefile, the main problem is that i don't know how to edit the makefile to link the library.
Anyone can help me? please!
Hi! Im working in a new project, and i need use modbus tcp/ip... the current project has already a makefile, the main problem is that i don't know how to edit the makefile to link the library.
Anyone can help me? please!
Hi! Im working in a new project, and i need use modbus tcp/ip... the current project has already a makefile, the main problem is that i don't know how to edit the makefile to link the library.
Anyone can help me? please!
this is the make file
# Copyright © 2003 NOAO
#
# Behzad Abareshi <behzad#noao.edu>
# National Optical Astronomy Observatories
# 950 N Cherry Ave, Tucson AZ 85719, USA
#-------------------------------------------------------------------------------
# Makefile
# 1 Jan 2002
#
#-------------------------------------------------------------------------------
CC = gcc
CFLAGS = -Wall -Winline -pedantic -std=gnu99
#CFLAGS += -Wshadow -Wbad-function-cast -Wcast-qual -Wwrite-strings -Wconversion
#CFLAGS += -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
#CFLAGS += -Wredundant-decls -Wnested-externs -Wunreachable-code
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS += -Wredundant-decls -Wnested-externs
#CFLAGS += -Wunreachable-code
DEFS += -DHYDRA_TWO_NAMESPACE
DEFS += -DHYDRA_II_SPEEDY
DEFS += -DHYDRA_II_SPEEDY_LEVEL_2
DEFS += -DHYDRA_II_PROTOCOL
# special builds:
#
#DEFS += -DHYDRA_II_TEST_MODE
#DEFS += -DHYDRA_II_SLOW_MODE
# engineering:
#DEFS += -DHYDRA_II_TUNE_MODELS
#DEFS += -DHYDRA_II_TUNE_Z
#DEFS += -DHYDRA_II_TUNE_Z_NO_SANITY
#DEFS += -DHYDRA_II_TUNE_Z_PAUSE
#DEFS += -DHYDRA_II_TRACE_SKIP_Z_MOUNT_PROBLEM
#
# debug 8051 response time
#DEFS += -DDEBUG_8051_RESPONSE_TIME
ifeq ($(MODE),sim)
DEFS += -DHYDRA_II_SIMULATOR
DEFS += -DHYDRA_II_SIMULATOR_UNREAL_TIME
DEFS += -DHYDRA_II_SIMULATOR_FAKE_IT
endif
LIBROOT = libhydra2
STATIC_LIB = $(LIBROOT).a
CFLAGS += -fPIC
LIBVER = 1
LIBMV = 0
LIBRN = 1
SONAME = $(LIBROOT).so.$(LIBVER)
DYNAMIC_LIB = $(SONAME).$(LIBMV).$(LIBRN)
LIBFLAGS = -shared -Wl,-soname,$(SONAME) -o $(DYNAMIC_LIB) -lc
ifeq ($(STATIC),YES)
LIBS += -static
endif
LIBS += -L ./ -lhydra2 -lreadline -lncurses -lc -lm -ltermcap
ifeq ($(OPTIMIZED),YES)
CFLAGS += -O3
else
CFLAGS += -O0 -ggdb
endif
HDRS = hydra_cli.h \
hydra_cli_private.h \
hydra_com.h \
hydra_common.h \
hydra_com_private.h \
hydra_config.h \
hydra_log.h \
hydra_log_private.h \
hydra_mc.h \
hydra_mc_protected.h \
hydra_mc_private.h \
hydra_sim.h \
hydra_sim_private.h \
hydra_models.h \
hydra_models_private.h \
hydra_Tsensor.h \
hydra_Tsensor_private.h \
hydra_sleep.h \
hydra_sleep_private.h \
hydra_sm.h \
hydra_sm_private.h \
hydra_sm_protected.h \
hydra_system.h \
hydra_system_private.h \
hydra_tools.h \
hydra_tools_private.h \
instruction_set.h \
smart_motor.h \
smart_motor_private.h \
smart_motor_protected.h
SRCS = hydra_sleep.c \
hydra_log.c \
hydra_com.c \
smart_motor.c \
hydra_tools.c \
hydra_models.c \
hydra_sm.c \
hydra_Tsensor.c \
hydra_mc.c \
hydra_sim.c \
hydra_cli.c \
hydra_system.c
OBJS = $(SRCS:.c=.o)
#
#-------------------------------------------------------------------------------
.c.o:
$(CC) -c $(CFLAGS) $(DEFS) $(INCS) $<
.SUFFIXES: .c .o
#
#-------------------------------------------------------------------------------
TARGETS = hc hcli mc_test model_test system_test sensor_test
LIB_INST = $(HYDRA)/lib
ifeq ($(TYPE),package)
APP_INST = $(PACKAGE)/bin.base
else
APP_INST = $(HYDRA)/bin.base
endif
#
#-------------------------------------------------------------------------------
all: .build $(STATIC_LIB) $(TARGETS)
.build: $(SRCS) $(HDRS) Makefile
#-rm -f *.o *.a
perl -p -i -w -e 's/(BUILD_NUMBER\s\()(\d+)(\)\s)/$$1 . ($$2 + 1) . $$3/eg;' hydra_common.h
touch .build
$(OBJS): .build
$(STATIC_LIB): $(OBJS)
ar rcs $(STATIC_LIB) $(OBJS)
$(DYNAMIC_LIB): $(OBJS)
$(CC) $(LIBFLAGS) $(OBJS)
rm -f $(SONAME) $(LIBROOT).so
ln -s $(DYNAMIC_LIB) $(SONAME)
ln -s $(DYNAMIC_LIB) $(LIBROOT).so
hc: hc.o $(STATIC_LIB)
$(CC) -o $# $< $(LIBS)
hcli: hcli.o $(STATIC_LIB)
$(CC) -o $# $< $(LIBS)
mc_test: hydra_mc_test.o $(STATIC_LIB)
$(CC) -o $# $< $(LIBS)
system_test: hydra_system_test.o $(STATIC_LIB)
$(CC) -o $# $< $(LIBS)
model_test: hydra_models_test.o $(STATIC_LIB)
$(CC) -o $# $< $(LIBS)
sensor_test: hydra_Tsensor_test.o $(STATIC_LIB)
$(CC) -o $# $< $(LIBS)
clean:
#-rm -f *.o *.a $(TARGETS) *.so* *log core* *~
install:
install $(STATIC_LIB) $(LIB_INST)
ifeq ($(MODE),sim)
else
install mc_test $(APP_INST)
install hcli $(APP_INST)
endif
rml:
#-rm -f *.log /tmp/*.LCK
BUILD := $(shell date +%H.%M.%S_%y.%h.%d)
TREE := $(shell basename `pwd`)
tar: clean
#echo
#echo "making tarball ..."
#cd ..; tar czf $(BUILD)_$(TREE).tgz $(TREE)
#echo "done!"
.PHONY: all install clean tar rml
And This is the code
/*
Copyright © 2004 NOAO
Behzad Abareshi <behzad#noao.edu>
National Optical Astronomy Observatories
950 N Cherry Ave, Tucson AZ 85719, USA
------------------------------------------------------------------------------*/
/*
** hydra_com.c
** 13 Jan 2004 : Hydra II communication module.
**
*/
/* headers
------------------------------------------------------------------------------*/
#include "hydra_com_private.h"
#include "/usr/local/include/modbus/modbus.h"
#include "/home/hydra/Downloads/libmodbus-3.1.6/tests/unit-test.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
const int EXCEPTION_RC = 2;
enum {
TCP,
TCP_PI,
RTU
};
int modbus(int argc, char *argv[])
{
const int NB_REPORT_SLAVE_ID = 10;
uint8_t *tab_rp_bits = NULL;
uint16_t *tab_rp_registers = NULL;
uint16_t *tab_rp_registers_bad = NULL;
modbus_t *ctx = NULL;
int i;
uint8_t value;
int nb_points;
int rc;
float real;
uint32_t old_response_to_sec;
uint32_t old_response_to_usec;
uint32_t new_response_to_sec;
uint32_t new_response_to_usec;
uint32_t old_byte_to_sec;
uint32_t old_byte_to_usec;
int use_backend;
int success = FALSE;
int old_slave;
ctx = modbus_new_tcp("192.168.1.40", 502);
modbus_set_debug(ctx, TRUE);
modbus_set_error_recovery(ctx,
MODBUS_ERROR_RECOVERY_LINK |
MODBUS_ERROR_RECOVERY_PROTOCOL);
if (use_backend == RTU) {
modbus_set_slave(ctx, SERVER_ID);
}
modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
modbus_get_response_timeout(ctx, &new_response_to_sec, &new_response_to_usec);
/* Allocate and initialize the memory to store the bits */
nb_points = (UT_BITS_NB > UT_INPUT_BITS_NB) ? UT_BITS_NB : UT_INPUT_BITS_NB;
tab_rp_bits = (uint8_t *) malloc(nb_points * sizeof(uint8_t));
memset(tab_rp_bits, 0, nb_points * sizeof(uint8_t));
/* Allocate and initialize the memory to store the registers */
nb_points = (UT_REGISTERS_NB > UT_INPUT_REGISTERS_NB) ?
UT_REGISTERS_NB : UT_INPUT_REGISTERS_NB;
tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
/** Read REGISTERS **/
rc = modbus_read_registers(ctx, 2000,1, tab_rp_registers);
/** Write REGISTERS **/
rc = modbus_write_register(ctx, 50, 110);
modbus_close(ctx);
modbus_free(ctx);
}
/* globals
------------------------------------------------------------------------------*/
char CL [HC_BUF_SIZE];
bool VERBOSE = false;
static Device device [HC_DEVICES_MAX];
static unsigned short device_count;
static unsigned char MODE;
static char msg [HC_BUF_SIZE];
static Log_Unit log_unit;
/*==============================================================================
** broadcast
**
*/
int broadcast (char *cl, char *reply[])
{
int rt_val = OK;
unsigned short i;
for (i = 0; i < device_count; ++i)
{
if (device[i].global_member && device[i].original)
{
char cmd [HC_BUF_SIZE];
strcpy (cmd, cl);
sprintf (msg, "[%s] broadcast on %s\n", cl, device[i].port);
hc_log (VERBOSE ? 2 : 0, msg);
if (MODE & REAL_COMMUNICATION)
{
if (talk (&device[i], cmd, reply) == ERR)
{
sprintf (msg, "ERROR: broadcast to device %hu\n", device[i].id);
hc_log (2, msg);
rt_val = ERR;
}
}
else
{
simulator (cmd, reply);
}
}
}
return rt_val;
}
/*==============================================================================
** com_end
**
*/
int com_end (void)
{
if (MODE & REAL_COMMUNICATION)
{
return ports_close();
}
return OK;
}
/*==============================================================================
** com_init
**
*/
int com_init (const char *cfg_file, const char *end_char, unsigned short ms_timeout, unsigned char mode)
{
unsigned short i;
strcpy (log_unit.tag, "Hydra_com");
if (log_init (&log_unit) == ERR)
{
fprintf (stderr, "%s\n", "hydra_com: FATAL: could not initiate logging");
exit (ERR);
}
hc_log (VERBOSE ? 2 : 0, version());
sprintf (msg, "PID: %d", getpid());
hc_log (0, msg);
MODE = mode;
#ifdef HYDRA_II_SIMULATOR
MODE = 0x00;
#endif
rd_cfg (cfg_file);
if (MODE & REAL_COMMUNICATION)
{
ports_open();
}
else
{
sim_init();
}
for (i = 0; i < device_count; ++i)
{
strcpy (device[i].end_char, end_char);
device[i].ms_timeout = ms_timeout;
sprintf (msg, "\n[%4hu] [%25s] fd[%2d] sa[%10lu] original[%s] global[%s] strip[%s]\n",
device[i].id, device[i].port, device[i].fd, device[i].s_addr,
device[i].original ? "Y" : "N",
device[i].global_member ? "Y" : "N",
device[i].strip_id ? "Y" : "N");
hc_log (VERBOSE ? 2 : 0, msg);
}
return OK;
}
/*==============================================================================
** device_lock
**
*/
static int device_lock (Device *device)
{
if (0 == device->s_addr)
{
char *base = strrchr (device->port, '/');
sprintf (device->lock, "/tmp/%s.LCK", base ? base + 1 : device->port);
}
else
{
sprintf (device->lock, "/tmp/%lu.LCK", device->s_addr);
}
sprintf (msg, "creating lock [%s]\n", device->lock);
hc_log (VERBOSE ? 2 : 0, msg);
if (open (device->lock, O_RDWR | O_CREAT | O_EXCL , 0444) == ERR)
{
perror (device->lock);
exit (ERR);
}
return OK;
}
/*==============================================================================
** device_unlock
**
*/
static int device_unlock (Device *device)
{
sprintf (msg, "removing lock [%s]\n", device->lock);
hc_log (VERBOSE ? 2 : 0, msg);
if (access (device->lock, F_OK) == OK)
{
if (unlink (device->lock) == ERR)
{
perror (device->lock);
return ERR;
}
}
else
{
perror (device->lock);
return ERR;
}
return OK;
}
/*==============================================================================
** get_cl
**
*/
int get_cl (const char *prompt)
{
char *cl = (NULL == prompt) ? readline ("> ") : readline (prompt);
if (cl == NULL) return ERR;
// account for null and optional end char
if (strlen (cl) >= sizeof (CL) - 2)
{
hc_log (2, "ERROR: command too big: ignored\n");
return ERR;
}
bzero (CL, sizeof (CL));
strcpy (CL, cl);
free (cl);
// get rid of precdeing blanks
cl = CL;
while (isspace (*cl)) cl++;
strcpy (CL, cl);
if (*CL) add_history (CL);
return OK;
}
/*==============================================================================
** hc_log
**
*/
int hc_log (int pipe, char *msg)
{
return log_it (&log_unit, pipe, msg);
}
/*==============================================================================
** open_serial
**
*/
static int open_serial (Device *device)
{
struct termios s_t;
if ((device->fd = open (device->port, O_RDWR | O_NOCTTY)) == ERR)
{
perror (device->port);
exit (ERR);
}
memset( &s_t, 0, sizeof( s_t ) );
if (cfsetispeed (&s_t, B38400) == ERR)
{
perror (device->port);
exit (ERR);
}
if (cfsetospeed (&s_t, B38400) == ERR)
{
perror (device->port);
exit (ERR);
}
s_t.c_cflag |= (CS8 | CLOCAL | HUPCL | CREAD);
// Critical for canonical communication.
s_t.c_iflag &= ~(IGNCR);
s_t.c_iflag |= ICRNL;
#ifdef NON_CANONICAL
// Essential to make sure we capture all the characters
// when reading responses.
// NOTE: we could use 0 for both to make communication faster
// and more efiicient, but then we have to carefully make the read
// in talk() work in a loop and read until a newline is detected.
// Note how we intentionally DO NOT ignore CR and convert it to NL.
s_t.c_cc [VMIN] = 16;
s_t.c_cc [VTIME] = 1;
#else
s_t.c_lflag |= ICANON;
#endif
// NON_CANONICAL
if (tcsetattr (device->fd, TCSANOW, &s_t) == ERR)
{
perror (device->port);
exit (ERR);
}
if (tcflush (device->fd, TCIOFLUSH) == ERR)
{
perror (device->port);
exit (ERR);
}
return OK;
}
/*==============================================================================
** open_socket
**
*/
static int open_socket (Device *device)
{
size_t adr_len;
int fd = socket (AF_INET, SOCK_STREAM, 0);
struct sockaddr_in adr;
adr.sin_addr.s_addr = device->s_addr;
adr.sin_family = AF_INET;
adr.sin_port = htons (HC_ISERVER_PORT);
adr_len = sizeof(adr);
}

Issue with my C program : compilation error occurs

I am using Yocto project cross-compiler to compile my C code.
But for some reasons I have compilation errors.
This is my C code :
#include <stdio.h>
#include <stdlib.h>
#include "/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa.hpp"
/* MRAA does not yet understand GPIO-A - GPIO-L */
/* Linaro will add this */
/* What Mraa does understand is pin out numbers so, */
/* pin 23 is GPIO-A and pin 25 is GPIO-C */
#define LED 10
#define BUTTON 29
bool running = true;
bool led_state = false;
int last_touch;
void sig_handler(int signo)
{
if (signo == SIGINT)
running = false;
}
int main(int argc, char* argv[])
{
mraa::Result ret;
int touch;
mraa::Gpio* touch_gpio = new mraa::Gpio(BUTTON);
if (touch_gpio == NULL){
return mraa::ERROR_UNSPECIFIED;
}
mraa::Gpio* led_gpio = new mraa::Gpio(LED);
if (led_gpio == NULL){
return mraa::ERROR_UNSPECIFIED;
}
signal(SIGINT, sig_handler);
if ((ret = touch_gpio->dir(mraa::DIR_IN))!= mraa::SUCCESS){
return ret;
}
if ((ret = led_gpio->dir(mraa::DIR_OUT))!= mraa::SUCCESS){
return ret;
}
led_gpio->write(led_state);
while (running) {
touch = touch_gpio->read();
if (touch == 1 && last_touch == 0) {
led_state = !led_state;
ret = led_gpio->write(led_state);
usleep(100000);
}
last_touch = touch;
usleep(1);
}
delete led_gpio;
delete touch_gpio;
return ret;
}
This is the Makefile :
#CC=arm-poky-linux-gnueabi-gcc -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a5 --sysroot=/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi
#CC="gcc"
all: last1.o
${CC} last1.o -o target_bin -lmraa
last1.o: last1.c
${CC} -I . -c last1.c
clean:
rm -rf *.o
rm target_bin
And this is what I get when i run make all :
In file included from
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/common.hpp:28:0,
from /home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa.hpp:27,
from last1.c:4:
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/types.hpp:32:1:
error: unknown type name ‘namespace’ namespace mraa ^~~~~~~~~
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/types.hpp:33:1:
error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘{’
token { ^
In file included from
/home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa.hpp:27:0,
from last1.c:4: /home/gaston/linux4sam/poky/build-microchip/tmp/sysroots-components/cortexa5hf-neon/mraa/usr/include/mraa/common.hpp:29:10:
fatal error: string: No such file or directory #include
^~~~~~~~
compilation terminated. Makefile:8: recipe for target 'last1.o' failed
make: *** [last1.o] Error 1
You are compiling your code written in C with a C++ compiler.
Just change your .c files to .cpp files, and compile using g++ rather than gcc if you are on Unix systems.

ppu-ld cannot find -lspe

I am trying to compile the code below, on CELL BE Simulator(mambo).
//hello.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <libspe.h>
#include <sched.h>
extern spe_program_handle_t hello_spu;
spe_gid_t gid;
speid_t speids[8];
int status[8];
int main(int argc, char *argv[]){
int i;
printf("Hello World!\n");
gid = spe_create_group (SCHED_OTHER, 0, 1);
if (gid == NULL) {
fprintf(stderr, "Failed spe_create_group(errno=%d)\n", errno);
return -1;
}
if (spe_group_max (gid) < 8) {
fprintf(stderr, "System doesn't have eight working SPEs. I'm leaving.\n");
return -1;
}
for (i = 0; i < 8; i++) {
speids[i] = spe_create_thread (gid, &hello_spu,NULL, NULL, -1, 0);
if (speids[i] == NULL) {
fprintf (stderr, "FAILED: spe_create_thread(num=%d, errno=%d)\n",i, errno);
exit (3+i);
}
}
for (i=0; i<8; ++i){
spe_wait(speids[i], &status[i], 0);
}
__asm__ __volatile__ ("sync" : : : "memory");
return 0;
}
//Makefile
########################################################################
# Target
########################################################################
PROGRAM_ppu64 = hello
########################################################################
# Local Defines
########################################################################
IMPORTS = ../spu/hello_spu.a -lspe
########################################################################
# make.footer
########################################################################
include /opt/cell/sdk/buildutils/make.footer
After compiling the this, it provides with the following output.
$make
/opt/cell/toolchain/bin/ppu-gcc -W -Wall -Winline -I. -I /opt/cell/sysroot usr/include -I /opt/cell/sysroot/opt/cell/sdk/usr/include -mabi=altivec -maltivec -O3 -c
hello.c
hello.c: In function 'main':
hello.c:12: warning: unused parameter 'argc'
hello.c:12: warning: unused parameter 'argv'
/opt/cell/toolchain/bin/ppu-gcc -o hello hello.o -L/opt/cell/sysroot/usr/lib64 -L/opt/cell/sysroot/opt/cell/sdk/usr/lib64 -R/opt/cell/sdk/usr/lib64 ../spu/hello_spu.a -lspe
/opt/cell/toolchain/bin/ppu-ld: cannot find -lspe
collect2: ld returned 1 exit status
make: *** [hello] Error 1
'ld' cannot find the -lspe library.The "/opt/cell/sysroot/usr/lib" directory contains following libraries and files,
alf, libblas.so, libc_stubs.a, libieee.a, libnetpbm.so.10, libnuma.so.1, libsimdmath.so.3,
crt1.o, libblas.so.1, libdl.a, libm.a, libnetpbm.so.10.35, libpthread.a, libsimdmath.so.3.0.3,
crti.o, libBrokenLocale.a, libdl.so, libmass.a, libnldbl_nonshared.a, libpthread_nonshared.a, libspe2.so,
crtn.o, libBrokenLocale.so, libg.a, libmassv.a, libnsl.a, libpthread.so, libspe2.so.2,
gconv, libbsd.a, libgmp.a, libmcheck.a, libnsl.so, libresolv.a, libspe2.so.2.2.0,
gcrt1.o, libbsd-compat.a, libgmp.so, libmp.a, libnss_compat.so, libresolv.so, libthread_db.so,
libalf.a, libc.a, libgmp.so.3, libmpfr.a, libnss_dns.so, librpcsvc.a, libutil.a,
libalf.so, libcidn.so, libgmp.so.3.3.3, libmp.so, libnss_files.so, librt.a, libutil.so,
libalf.so.3, libc_nonshared.a, libgmpxx.a, libmp.so.3, libnss_hesiod.so, librtkaio.a, Mcrt1.o,
libalf.so.3.0.0, libcrypt.a, libgmpxx.so, libmp.so.3.1.7, libnss_nisplus.so, librt.so, Scrt1.o,
libanl.a, libcrypt.so, libgmpxx.so.3, libm.so, libnss_nis.so, libsimdmath.a,
libanl.so, libc.so, libgmpxx.so.3.0.5, libnetpbm.so, libnuma.so, libsimdmath.so
How do I link libspe2.so to libspe.so?
Please, help.
You don't link those together. They are different things. You either update your makefile to use -lspe2 if that's the version of the library you want or you install the version of the library that installs the libspe.so library.

Error while including header file using make

I have to compile two independent processes-sendfdsock.c and recvfdsock.c using make file. Both the files have there own main function. This means they are independent and I have to compile them as two different binaries. This is my make file:
compileAll:sendfdsock recvfdsock
sendfdsock:sendfdsock.o
gcc -o sendfdsock sendfdsock.o
sendfdsock.o:sendfdsock.c accessories.h
gcc -c sendfdsock.c
recvfdsock.o:recvfdsock.c accessories.h
gcc -c recvfdsock.c
recvfdsock:recvfdsock.o
gcc -o recvfdsock recvfdsock.o
Here I have made a compileAll target which compiles both the files.
Both files need to use accessories.h. As mention in GNU Make Doc - A simple Make file. I wrote this make file.
accessories.h :
#include <malloc.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <error.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <stropts.h>
#define PORT "4444" //port we are listening on
int sendall(int fd, char *buf, int *len);
int recvall(int fd, char *buf, int *len);
void logp(int typ, char* msg);
void errorp(char *where, int boolean, int errn,char *what);
accessories.c :
#include "accessories.h"
void logp(int typ, char* msg) // typ --> type(category) of message [1-Normal Log, 2-Warning(any unexpected thing happened), 3-Error, 4-Debugging Log ]
{
int fd;
time_t now;
ssize_t wlength=0;
char * dat;
char * str;
int size = 45+strlen(msg);//14+24+5+sizeof msg+1
str= (char *) malloc(size);
time(&now);//system time in seconds
dat = ctime(&now); // converting seconds to date-time format
dat = strtok(dat,"\n");
//Appending type of log
switch(typ)
{
case 1:
strcpy(str,"__LOG__ | ");
strcat(str,dat);
break;
case 2:
strcpy(str,"__WARN__ | ");
strcat(str,dat);
break;
case 3:
strcpy(str,"__ERR__ | ");
strcat(str,dat);
break;
case 4:
strcpy(str,"__DEBUG__ | ");
strcat(str,dat);
break;
default:
strcpy(str,"__UNDEF__ | ");
strcat(str,dat);
break;
}
strcat(str," | ");
strcat(str,msg);//appending message
strcat(str,"\n");
fd = open("log", O_WRONLY | O_CREAT | O_APPEND, 0644); // should be opened somewhere else
if (fd == -1)
printf("Could not open log - %s\n",strerror(errno));
else
{//need to add lock to the file and printing error message
while ( wlength < strlen(str) )
{
wlength = write(fd, str,strlen(str));
if (wlength == -1)
{
printf("Error : writing log\n");
break;
}
}
}
}
int sendall(int fd, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;
while(total < *len) {
n = send(fd, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
}
int recvall(int fd, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;
while(total < *len) {
n = recv(fd, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
}
void errorp(char *where, int boolean, int errn,char *what)
{
char errmsg[21+strlen(where)];
strcpy(errmsg,"Where - ");
strcat(errmsg,where);
strcat(errmsg," | Error - ");
if(boolean == 1)//we got error number
{
strcat(errmsg,strerror(errn));
//fprintf(stderr,"ERROR - In %s and error is %s\n",where ,strerror(errn));
logp(3,errmsg);
}
else if(boolean == 0)//we got a message
{
strcat(errmsg,what);
//fprintf(stderr,"ERROR - In %s and error is %s\n",where ,what);
logp(3,errmsg);
}
else//we got nothing
{
strcat(errmsg,"No Message");
//fprintf(stderr,"ERROR - In %s\n",where);
logp(3,errmsg);
}
}
Initially everything work fine but when I trid to use any function which is defined in accessories.c compilation give me error.
For example I use the log function in sendfdsock.c :
#include "accessories.h"
#define CONTROLLEN CMSG_LEN(sizeof(int))
static struct cmsghdr *cmptr = NULL; /* malloc'ed first time */
int send_err(int fd, int errcode, const char *msg);
int send_fd(int fd, int fd_to_send);
int main(int argc, char const *argv[])
{
logp(1,"started"); //This function is defined in accessories.c
int fd_to_send;
if((fd_to_send = open("vi",O_RDONLY)) < 0)
printf("vi open failed");
struct sockaddr_un address;
int socket_fd, nbytes;
char buffer[256];
........
Output of the compilation is:
abhi#abhi-me:~/bridge/server$ make compileAll
gcc -c sendfdsock.c
sendfdsock.c: In function ‘send_fd’:
sendfdsock.c:111:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘ssize_t’ [-Wformat]
sendfdsock.c:114:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘ssize_t’ [-Wformat]
gcc -o sendfdsock sendfdsock.o
sendfdsock.o: In function `main':
sendfdsock.c:(.text+0x32): undefined reference to `logp'
collect2: ld returned 1 exit status
make: *** [sendfdsock] Error 1
abhi#abhi-me:~/bridge/server$
Why undefined reference to logp error?
Why I don't write accessories.o in final linking:
But as this example is given in GNU Make Doc:
In this example, all the C files include ‘defs.h’, but
only those defining editing comminclude ‘command.h’, and only
low level files that change the editor buffer include 'buffer.h':
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
Here while linking all the files in edit they don't write defs.o or buffer.o. Means while linking they are not including object files of header files. Also they have not written any target like: defs.o or buffer.o
Why?
You just missed accessories.o in both linking targets. Something like this:
accessories.o: accessories.c
sendfdsock: sendfdsock.o accessories.o
$(CC) -o $# $(CFLAGS) $(LDFLAGS) $+
Also, consider using the built-in rules, just modify their parameters, if needed. See make -p for the full list (and makes infopage)
You misunderstand the relationship between source files, header files and object files.
Suppose I have the following four files:
//foo.h
#define PI 3.1
//bar.h
void func();
//bar.c
#include "foo.h"
#include "bar.h"
void func()
{
...
}
//baz.c
#include "foo.h"
#include "bar.h"
int main()
{
func();
}
(I left out the header guards, I presume you know about those.) I must use the compiler to produce an object file from each source file: bar.c -> bar.o and baz.c -> baz.o. I don't have to make object files from the headers foo.h and bar.h, those will simply be #included by any source file that needs them. Then I link the object files together to form an executable:
baz: bar.o baz.o
gcc -o baz bar.o baz.o
bar.o: bar.c foo.h bar.h
gcc -c bar.c
baz.o: baz.c foo.h bar.h
gcc -c baz.c
If I neglect to link bar.o into the executable, I'll get a linker error when the linker gets to the place where baz calls func() and the linker doesn't know what to put there (because it lacks the definition of func() in bar.o):
baz.o: In function `main':
baz.c:(.text+0x32): undefined reference to `func()'
So the GNU Make doc is correct, and as Alex said, your rule should have:
sendfdsock:sendfdsock.o accessories.o
...
accessories.o: accessories.c accessories.h
...
(Incidentally, once you get this makefile working, we can show you how to make it more concise.)

pthread_create failed and returned -1 (or 4294967295)

I'm trying to reproduce an example from Network Security with OpenSSL (by Chandra et al). The program consists of client.c server.c common.h and common.c. client.c simply creates a connection to the server on port 6012 and reads data from stdin and then send those data to the server. The server.c reads data from socket and writes it back out to stdout.
The problem is that server.c always get stuck in if(BIO_do_accept(acc) <= 0) at line 62 and never gets data sent from client.c, which runs perfectly fine. I later found the problem is that pthread_create(...) at line 66 ( which is defined as THREAD_CREATE(...) in common.h) failed and it returned 4294967295. Because THREAD_CREATE(...) failed, the program never get a chance to run do_server_loop in server_thread(...), which explains why the server never got the data from client.
How should I interpret the return values from pthread_create and how should I fix it?
PS. I later used strerror to convert 4294967295 and it returned "Unknown error".
Any help will be much appreciated!
//////////////////////////////////////////////////
Here is server.c:
#include "common.h"
void do_server_loop(BIO *conn)
{
int err, nread;
char buf[80];
do
{
fprintf(stderr, "server_loop executed.\n");
for(nread = 0; nread < sizeof(buf); nread += err)
{
err = BIO_read(conn, buf + nread, sizeof(buf) - nread);
if(err <= 0){
break;
}
}
fwrite(buf, 1, nread, stdout);
}
while (err > 0);
}
void THREAD_CC server_thread(void *arg)
{
fprintf(stderr, "server_thread(void *arg) executed.\n");
BIO *client = (BIO *)arg;
#ifndef WIN32
pthread_detach(pthread_self());
#endif
fprintf(stderr, "Connection opened.\n");
do_server_loop(client);
fprintf(stderr, "Connection closed.\n");
BIO_free(client);
ERR_remove_state(0);
#ifdef WIN32
_endthread();
#else
return 0;
#endif
}
int main(int argc, char *argv[])
{
BIO *acc, *client;
int thread_create_result;
THREAD_TYPE tid;
init_OpenSSL();
acc = BIO_new_accept(PORT);
if(!acc){
int_error("Error creating server socket");
}
if(BIO_do_accept(acc) <= 0){
int_error("Error binding server socket");
}
for(;;)
{
if(BIO_do_accept(acc) <= 0){
int_error("Error accepting connection");
}
client = BIO_pop(acc);
thread_create_result = THREAD_CREATE(tid, server_thread, client);
if(thread_create_result != 0){
fprintf(stderr, "THREAD_CREATE failed! returns: %s.\n", \
strerror(thread_create_result));
fprintf(stderr, "thread_create_result has the value: %u.\n", \
thread_create_result);
exit(-1);
}
}
BIO_free(acc);
return 0;
}
Here is common.h
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef WIN32
#include <pthread.h>
#define THREAD_CC *
#define THREAD_TYPE pthread_t
#define THREAD_CREATE(tid, entry, arg) pthread_create(&(tid), NULL, \
(entry), (arg))
#else
#include <windows.h>
#include <process.h>
#define THREAD_CC __cdecl
#define THREAD_TYPE DWORD
#define THREAD_CREATE(tid, entry, arg) do { _beginthread((entry), 0, (arg));\
(tid) = GetCurrentThreadId();\
} while (0)
#endif
#define PORT "6012" //port
#define SERVER "10.1.251.24" //server address
#define CLIENT "10.1.21.46" //client address
#define int_error(msg) handle_error(__FILE__, __LINE__, msg)
void handle_error(const char *file, int lineno, const char *msg);
void init_OpenSSL(void);
Makefile:
CC = gcc
OPENSSLDIR = /usr/local/ssl
#CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2
RPATH = -R${OPENSSLDIR}/lib
#LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread
LD = -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -pthread
OBJS = common.o
PROGS = server
all: ${PROGS}
server: server.o ${OBJS}
${CC} server.o ${OBJS} -o server ${LD}
clean:;
${RM} ${PROGS} *.ln *.BAK *.bak *.o
Change
if(thread_create_result = !0){
to
if(thread_create_result != 0){
Besides, you can use strerror function to convert error code to human-readable form.
add -D_REENTRANT on compile command lines and -lpthread on the link command line.
-D_REENTRANT will tell C/C++ libraries that your program is in multithread mode and -lpthread just load the shared library libpthread.so at runtime. I found this at William Garrison's POSIX threads tutorial and this link.
Here is the Makefile:
CC = gcc
OPENSSLDIR = /usr/local/ssl
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__
RPATH = -R${OPENSSLDIR}/lib
LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread
OBJS = common.o
PROGS = server
all: ${PROGS}
server: server.o ${OBJS}
${CC} server.o ${OBJS} -o server ${LD}
clean:;
${RM} ${PROGS} *.ln *.BAK *.bak *.o

Resources