Posix Semaphore compilation error using the -lrt [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
sem_open() error: “undefined reference to sem_open()” on linux (Ubuntu 10.10)
Having issues with compilation of posix semaphores. My goal is to create a shared memory segment and protect it by semaphores. shared memory works fine but semaphores code gives me compilation errors even though I included semaphore.h and added -lrt to compilation flags
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <time.h>
int main (int argc, char** argv) {
FILE *configFile;
int i,j;
int CashDesksNo=0;
int maxCashDesksNo;
int n,m;
int TmaxServe;
int custPerc; //customer ratio policy
int maxCapacity;
char * nlptr=NULL;
char * pch=NULL;
char line[125];
char termInput[30];
char tmpString[40];
int flg1,flg2;
int flag;
int execResult=0;
int fd;
int rc;
int randNum;
int status;
pid_t ch_pid;
int a,b,c;
int shmid=0;
int *shm_ptr;
int * err;
int retval;
sem_t *sp;
char semName[10];
strcpy(semName,"mutex");
//---------- Davasma kai elegxos in line parameters-----------------
// read inline params and config file
.
.
.
//------------ Print Configuration Data ----------------------------
if(CashDesksNo>maxCashDesksNo || CashDesksNo<1)
{
printf("\n# of Cash Desks should be between 1 and %d",maxCashDesksNo);
printf("\nsupermarket will now exit...\n");
exit(1);
}
printf("\n//-----------------------------------------------");
printf("\nSupermarket initialization");
printf("\n# of Cash Desks: %d",CashDesksNo);
printf("\n# of max products: %d",n);
printf("\nMax price: %d",m);
printf("\nMaximum serving time(secs): %d",TmaxServe);
printf("\n%% Customer/Cashier Percentage: %d/%d",custPerc,100-custPerc);
printf("\nMax Supermarket capacity: %d",maxCapacity);
printf("\n//-----------------------------------------------\n");
printf("\nAbout to create customer and cashier processes");
// ----------- Shared Memory Attachment --------------------------------
shmid=shmget(IPC_PRIVATE,sizeof(int*),0666);
if (shmid < 0)
{
perror("shmget");
exit(1);
}
shm_ptr=(int*)shmat(shmid,(void *)0,0);
if (shm_ptr == (int *)(-1))
{
perror("shmat");
exit(1);
}
a=0; //shm
shm_ptr=(int*)a;
printf("shmPtr:%d",(int)shm_ptr);
// ----- create & initialize semaphore ---------------------------------
sp = sem_open(semName,O_CREAT,0644,1);
if(sp == SEM_FAILED)
{
perror("unable to create semaphore");
exit(-1);
}
while(1)
{
printf("\nPress enter to start a new day at the supermarket(type exit to quit)\n");
fgets(termInput,sizeof(termInput),stdin);
nlptr = strchr(termInput, '\n');// termatismos string
if (nlptr) *nlptr = '\0';
if(strcmp(termInput,"exit")==0)//exit apo tin efarmogi
{
printf("\nExiting Supermarket..\n");
exit(0);
}
i=0;
while(i<maxCapacity)
{
//-Fork new process for the simulation --------------------
ch_pid = fork();
if (ch_pid == -1) {
perror("\nFailed to fork initial spliter/merger process \n");
exit(1);
}
if ( ch_pid == 0 ) //this is the child process
{
srand (getpid());//pid based seed
// "itoa" - Metatropi ari8mou se string
sprintf( tmpString, "%d", shmid );
randNum=rand() % 100 + 1;
if(randNum<custPerc)// customer : cashier ratio
{
execResult=execl("customer","customer","0",tmpString,NULL);
//printf("\nCreated a customer,randNum %d",randNum);
}else
{
execResult=execl("cashier","cashier","0",tmpString,NULL);
//printf("\nCreated a cashier,randNum %d",randNum);
}
if(execResult==-1)
{
perror("Could not perform exec to create cashier/customer process");
}
}
i++;
}
//Root process
//wait for childs to terminate
for (i = 0; i < maxCapacity; ++i)
{
waitpid(-1,&status,0);
}
printf("supermarket shared memory content: %d",(int)shm_ptr);
sem_close(sp);
sem_unlink(semName);
err = (int*)shmctl(shmid, IPC_RMID, 0);
if (err == -1)
perror ("Shared Memory Removal.");
else
printf("Shared Memory Removed. %d\n", (int)(err));
}
}
this is the makefile:
OBJS = supermarket.o cashier.o customer.o
SOURCE = supermarket.c cashier.c customer.c
HEADER = struct.h
OUT = supermarket cashier customer
CC = gcc
FLAGS = -lrt -g -c
LIBS = -lm
# -g option enables debugging mode
# -c flag generates object code for separate files
# -lm math library
all: supermarket cashier customer
supermarket: supermarket.c
$(CC) supermarket.c -o supermarket
cashier: cashier.c
$(CC) cashier.c -o cashier
customer: customer.c
$(CC) customer.c -o customer
# clean house
clean:
rm -f $(OBJS) $(OUT)
# do a bit of accounting
count:
wc $(SOURCE) $(HEADER)
I keep getting this error:
george#george-System-Product-Name:~/Desktop/prj3$ make
gcc supermarket.c -o supermarket
supermarket.c: In function ‘main’:
supermarket.c:310:11: warning: comparison between pointer and integer [enabled by default]
/tmp/ccYxA2Wi.o: In function `main':
supermarket.c:(.text+0x75c): undefined reference to `sem_open'
supermarket.c:(.text+0x9b0): undefined reference to `sem_close'
supermarket.c:(.text+0x9bf): undefined reference to `sem_unlink'
collect2: ld returned 1 exit status
make: *** [supermarket] Error 1
what can i do?
this is a project for operating systems class, my system is linux Ubuntu

I think you should link against pthread as well:
-lpthread
Example makefile from an old project of mine (see comments):
CC=gcc
CFLAGS=-c -Wall -O3 -g
LDFLAGS=-pthread
SOURCES=chatzor.c clientlist.c messagequeue.c
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=chatzor_server
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf *.o ${EXECUTABLE}

You're going to have sore shins once you're done with this.
The compilation trace says:
$ make
gcc supermarket.c -o supermarket
supermarket.c: In function ‘main’:
...
Your makefile says:
supermarket: supermarket.c
$(CC) supermarket.c -o supermarket
It should say (at minimum):
supermarket: supermarket.c
$(CC) supermarket.c -o supermarket $(LIBS)
Indeed, it should probably be saying:
supermarket: supermarket.c
$(CC) $(CFLAGS) supermarket.c -o supermarket $(LDFLAGS) $(LIBS)

Related

Can't make thread from a function in another file [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I have two files. sim.c and devices.c.
Here's the sim.c
...
#include "devices.h"
int main(int argc, char **argv) {
pthread_t *tid;
tid = (pthread_t *) malloc(sizeof(pthread_t) * 3);
// this is where I start the 3 threads located in devices.c
if (pthread_create(&tid[0], NULL, device_one, NULL)) {
exit(1);
}
if (pthread_create(&tid[1], NULL, device_two, NULL)) {
exit(1);
}
if (pthread_create(&tid[2], NULL, device_three, NULL)) {
exit(1);
}
// wait for 3 threads to finish
int i;
for (i = 0; i < 3; i++) {
if (pthread_join(tid[i], NULL)) {
exit(1);
}
}
}
Here's devices.c
...
#include "devices.h"
extern void *device_one(void *arg) {
printf("device one is called\n");
return NULL;
}
extern void *device_two(void *arg) {
printf("device two is called\n");
return NULL;
}
extern void *device_three(void *arg) {
printf("device three is called\n");
return NULL;
}
And here's devices.h
#ifndef DEVICES_H
#define DEVICES_H
extern void *device_one(void *arg);
extern void *device_two(void *arg);
extern void *device_three(void *arg);
However, when I compile, I get 3 errors under sim.c saying
undefined reference to 'device_one'
undefined reference to 'device_two'
undefined reference to 'device_three'
The errors suggest you are not linking with the devices module when compiling sim.c (which contains main). You could compile as:
gcc sim.c devices.c -I.
Or you can create a makefile:
CC = gcc
CFLAGS = -I.
DEPS = devices.h
OBJ = sim.o devices.o
LDLIBS = -pthread
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
sim: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LDLIBS)
.PHONY: clean
clean:
rm -rf $(OBJ)

How to link with linux/gpio.h?

I want to compile following c file:
#include <stdio.h>
#include <stdlib.h>
#include <../deps/linux/gpio.h>
int main(void) {
int r = gpio_is_valid(31);
if (r == -1) {
perror("GPIO address is invalid.\n");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
My Makefile looks as
build: gpio
LDFLAGS = -Llinux
gpio:
$(CC) -o gpio.o src/gpio.c $(LDFLAGS)
Unfortunately I get "gpio.h not found" as error.
gpio.h is a Linux kernel header. It can not be used for user space programs.

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.)

Error while linking libxml2

I have a simple example for libxml2 but it returns the following error:
$ gcc -Wall -lxml2 -I/usr/include/libxml2 -o ex1 ex1.c
/tmp/cc6OKSKJ.o: In function `main':
ex1.c:(.text+0x60): undefined reference to `xmlReadFile'
ex1.c:(.text+0x70): undefined reference to `xmlDocGetRootElement'
collect2: ld returned 1 exit status
$ xml2-config --libs
-lxml2
$ xml2-config --cflags
-I/usr/include/libxml2
I'm on Lubuntu 11.10 x86_64 and I have all the packages I need (well I think): libxml2, libxml2-dev, libxml2-dbg... Here's the code of the example:
// gcc -Wall -lxml2 -I/usr/include/libxml2 -o ex1 ex1.c
#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
int main(int argc, char **argv)
{
xmlDoc *document;
xmlNode *root, *first_child, *node;
char *filename;
if (argc < 2)
{
fprintf(stderr, "Usage: %s filename.xml\n", argv[0]);
return 1;
}
filename = argv[1];
document = xmlReadFile(filename, NULL, 0);
root = xmlDocGetRootElement(document);
fprintf(stdout, "Root is <%s> (%i)\n", root->name, root->type);
first_child = root->children;
for (node = first_child; node; node = node->next)
{
fprintf(stdout, "\t Child is <%s> (%i)\n", node->name, node->type);
}
fprintf(stdout, "...\n");
return 0;
}
Your link line is incorrect. Try
gcc -Wall -I/usr/include/libxml2 -o ex1 ex1.c -lxml2
Read this to understand why the order of sources and libraries on command line matters.

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