2

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

Community
  • 1
  • 1
George Panic
  • 431
  • 1
  • 8
  • 20
  • Maybe the POSIX semaphore functionality isn't enabled on the system. It used to be an optional part of POSIX (but is now in the base functionality). Which version of Ubuntu are you using? – Jonathan Leffler Jan 20 '12 at 00:23

2 Answers2

2

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}
Matthias van der Vlies
  • 3,834
  • 3
  • 24
  • 28
0

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)
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278