Solved

C code linking

Posted on 2001-06-06
14
2,774 Views
Last Modified: 2012-05-04


hi people
I was trying to compile a code using some
user defined shared libraries.
the name of the library he has kept is as

---------------------------------------------------
g++ -lsemphore -L./fifoimplementation semcreate.c

->undefined reference to sem_open(const char *, int. ...)
->undefined referenc to sem_close(sem_t *)

---------------------------------------------------

directory : ./fifoimplementation
***** libsemaphore.so.1,  
      libsemaphore.so -> libsemaphore.so.1

---------------------------------------------------


I used nm command on libsemaphore.so.1
(which is placed in ./fifoimplementation directory)
and it says "sem_close" and "sem_open" declared
with a T (normal) status.

I used gcc -c sem_open.c [to produce the sem_open.o file]
 gcc -c sem_close.c [to produce the sem_close.o file]
 gcc -shared -o libsemaphore.so.1 *.o [to produce
         the .so file]


below are the .c files .. u can cut these and try to
compile the library and use it
---------------------------------------------------

 

 


********************
/*semcreate.c - uses sem_open and sem_close :*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "./fifoimplementation/semaphore.h"

int
main(int argc, char **argv)
{
 int  c, flags;
 sem_t *sem;
 unsigned int value;

 flags = O_RDWR | O_CREAT;
 value = 1;
 while ( (c = getopt(argc, argv, "ei:")) != -1) {
  switch (c) {
  case 'e':
   flags |= O_EXCL;
   break;

  case 'i':
   value = atoi(optarg);
   break;
  }
 }
 if (optind != argc - 1)
  {printf("usage: semcreate [ -e ] [ -i initalvalue ] <name>");
  exit(0);}

 sem = sem_open(argv[optind], flags, S_IRWXU | S_IROTH | S_IRGRP, value);

 sem_close(sem);
 exit(0);
}
******************************


------------------------------------
when I try to compile it with
g++ -lsemaphore -L./fifoimplementation semcreate.c
is says undefined reference to sem_open and sem_close.
but they are there in the library and also in the header
file included.
-----------------------------------------

 

 

****************************
/*semaphore.h*/
 
typedef struct {
 int sem_fd[2];  /*2 fd's for reading and writing from the FIFO*/
 int sem_magic;  /*magic no*/
} sem_t;


#define SEM_MAGIC 0x92843

#ifdef SEM_FAILED
#undef SEM_FAILED
#define SEM_FAILED ((sem_t *) (-1)) /*this aviods compiler warnings ... I dont know*/
#endif


sem_t * sem_open(const char *, int, ...);
int sem_close(sem_t *);
int sem_wait(sem_t *);
int sem_post(sem_t *);
int sem_unlink(const char *);
***********************

 

 

*********************
/*sem_open.c
opening a semaphore in FIFO implementation
sem_open(const char *pathname, int oflags, ...)
if the O_CREAT flag is there in oflags we need
the rest of the two arguments namely int mode, int value*/

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>


sem_t *sem_open(const char *pathname, int oflags, ...)
{

int save_errno;
va_list ap;
mode_t mode;  /*mode of the file : O_RDWR, O_RDONLY etc*/
unsigned int value;
sem_t *sem;
int flags;
char c;
int i;

if (oflags & O_CREAT ==0) /*we are creating the semaphore */
 {
 va_start(ap, oflags);
 mode = va_arg(ap, mode_t);
 value = va_arg(ap, unsigned int);
 va_end(ap);

 if (mkfifo(pathname, mode)<0) /*the FIFO is created*/
 
if ( (errno ==EEXIST) && (oflags & O_EXCL)==0) /*file already exists and we have not set the O_EXEL flag*/
   oflags = ~O_CREAT;  /* we dont want to write the value of the semaphore */
                                   /*in the fifo as it is already there*/
  else
   return ((sem_t *) -1);
 }
 
 

/*allocate memory to the sem_t structure*/
sem = (sem_t *) malloc(sizeof(sem_t));

/*fifo created*/
( sem->sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK) <0)  /*an opening of the FIFO will block if */
 goto error;       /*i.e unlink the fifo created the other end hasen't opened it */
         /*we specify O_NONBLOCK to avoid the deadlock */
         /*and then turn off the O_NONBLOCK option */
         /*to wait for the semaphore values see fifo(4)*/
           

if (sem->sem_fd[1] = open(pathname, O_WRONLY | O_NONBLOCK) <0)
 goto error;

flags = fcntl(sem->sem_fd[0], F_GETFL);     /*get the current flags fot this file*/
flags &= ~O_NONBLOCK;                          /*reset O_NONBLOCK*/
fcntl(sem->sem_fd[0], F_SETFL, flags);       /*reset the flags*/

 

if (oflags & O_CREAT)        /*first time ... initialize the semaphore*/
 {
 for (i=0;i<value;i++)           /*write #value bytes to the fifo to init it*/
  if (write(sem->sem_fd[1], &c, 1)<0)
   goto error;
 }

sem->sem_magic = SEM_MAGIC;
return (sem);

error:
 save_errno = errno;      /*save errno lest it should get modified */
 if (oflags & O_CREAT ) unlink(pathname);
 close(sem->sem_fd[0]);     /*in this call*/
 close(sem->sem_fd[1]);
 free((void *) sem);
 errno = save_errno;      /*restore it*/
 return ((sem_t *) (-1));


}
********************

 

***********************
/*sem_close.c*/
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>


int sem_close(sem_t *sem)
{

if (sem->sem_magic != SEM_MAGIC)
 {
 errno = EINVAL;
 return (-1);
 }

sem->sem_magic = 0;  /*reset the magic number ... semaphore is now closed*/

if ( close(sem->sem_fd[0] ==-1 ) || close(sem->sem_fd[1] == -1) )
 {
 free(sem);
 return (-1);
 }

free(sem);
return (0);
}

*********************

 

 


-----------------------------------------------------------
if anybody can tell me the commands of how to
make libraries and also how to use the built in libraries,
I will be highly obliged !!!!!!!

Thankzzz
Gaurav.
-------------------------------------------------------------

 

0
Comment
Question by:GauravN4U
  • 6
  • 4
  • 4
14 Comments
 
LVL 5

Expert Comment

by:bryanh
ID: 6166464
Simple.  You're using gcc to create the library and g++ to link with it.  gcc and g++ use different translations between source code variables and object code symbols.  Since I don't see any non-C code in sem_create.c, just change g++ ... sem_create.c to gcc ... sem_create.c and it should work.
0
 

Author Comment

by:GauravN4U
ID: 6169186
plzzzzzz cut and copy this code and try to compile this
I have tried using both g++ and gcc. the mannual says g++ is a front eng for gcc !!
0
 
LVL 5

Expert Comment

by:bryanh
ID: 6171616
Sorry, that's way too much work for me.  But if you'd like to email the files to me at bryanh@giraffe-data.com, I'll give it a try.

Also, instead of posting your entire program, you should have cut it down to the smallest example that still demonstrates the problem.  That would be about 10 lines in two files.  That would make it easier for people to cut and paste it and also to see the problem.
0
 

Author Comment

by:GauravN4U
ID: 6171697
okieee
actually I just want to know how to build our own libraries and use them, in C.
I was able to make the .so files with the sem_open, and sem_close functions. but when I try to use them I get an error saying undefined reference .....



sorry about the sphagatti above but they are just 3 files.
But can't u just copy them into the files .... I have tried my level best to make it clear !!
Gaurav.

P.S: I am a newbie and am doing this stuff for the first time
0
 
LVL 5

Expert Comment

by:bryanh
ID: 6171804
You seem to know how to build your own libraries and use them in C.  Except for using g++ where you're supposed to use gcc, you're doing the same thing I do successfully.

But you said you get the same result if you use gcc.  I'd like to see some proof of that, like a session transcript like the one above, only with gcc instead of g++.  g++ is incapable of generating the error messages you get from g++.

g++, by the way, is a front end for gcc, but it invokes gcc with options that make it behave differently than ordinary gcc.

I'm 99% certain that your programs would build just fine for me.  Since there's so little chance of me learning anything by it, I don't want to go to the trouble of extracting them from the web page.  I don't know of any tools on my system to copy a large quantity of text from a web page into three files without a whole bunch of steps and tedious scrolling and mousing.  It's not something I normally do.  On the other hand, if you sent them to me as MIME attachments in email, it would only take a few quick keystrokes to put them in my home directory and run them through the compiler, so it might be worth the time.
0
 
LVL 5

Expert Comment

by:garboua
ID: 6177673
okay, I tried your code and it build OK.  
1.  
i compiled with both gcc and g++ and  a combination of both, IT works.
I had to modify /*fifo created*/
( sem->sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK) <0)  /*an opening of the FIFO will block if
*/
I could be a typo, but you were missing an "if"
2.
 I got rid of the hard coded include "./fifosutff" -- try Not to do that in the future, and configure directories using your  makefile
3.
[g&beavis]#g++ -c semaphore.c
[g&beavis]#ar -cr libSemaphore.a semaphore.o
[g&beavis]#g++ -c semcreate.c
[g&beavis]#g++ -L./ -lSemaphore semcreate.o -o SemaApps
works like a charm

PS.  using "goto" is NOT recommened at all.  try NOT to use it "a reason to be fired :-)"
there are better ways to catch errors "exception handling"

0
 
LVL 5

Expert Comment

by:garboua
ID: 6177740
oh, yeah, I removed prototype from header file and put it in semcreate.c as extern, should not matter either way.
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:GauravN4U
ID: 6183591
well well well .. I tried it too .... and it worked !
dammn I dont know what was wrong !
Thankzz
just one more thing ...
sem_open and other posix functions are also there in linux
in libpthread.so
but the posix sem_open function dosent work !!
when I do nm on libpthread
sem_open is marked with a T which means it is a normal implementation , still i can't seem to get it working
can u try to compile the semcreate.c with the posix implementations ??
any comments ??  Bryanh ??
Thankzz
0
 
LVL 5

Accepted Solution

by:
bryanh earned 100 total points
ID: 6184093
semcreate.o links with the routines in libpthread.so just fine for me.

To compile semcreate.c for the libpthread versions, I would need the interface header files for sem_open() and sem_close() and I either don't have them or don't know what they are.  In fact, I can't find any evidence that those are real interfaces.  The process synchronization calls in Posix threads are the "mutex" routines.  Are you sure these aren't internal library subroutines?
0
 

Author Comment

by:GauravN4U
ID: 6188111
well it compiles fine when linked with the libpthread.so.
but dosen't do the job.
I think the distro is not 100% posix compliant !!
I am using red hat 7.0 !
what do u say ??

Anywayzzz Thankzzz for the help.
It is highly appericiated.
Gaurav.


0
 
LVL 5

Expert Comment

by:garboua
ID: 6188398
look under /etc/include for pthread.h it must be there.
look under /lib for libthread.so and it should be there.  RH7.0 distribution is complete, the gcc compiler is funky though, VERY VERY VERY funky, be careful. there are plenty problem with their compiler, and it is NOT a standard release from gcc.  check with gcc -v and if you get 2.96 to to www.gnu.org and download latest stable release of gcc and install it, build it, same difference. linking with -lpthread should work find though.
0
 

Author Comment

by:GauravN4U
ID: 6192701
Hi garoba,
I had included pthread.h
and linked it with libpthread.so which was in /usr/lib
but sem_open function dosent seem to work
all the other functions sem_init sem_post etc
work fine ( if I use a memory based semaphore [sem_init])
So I think it is not there
Even the mannual page is not there for sem_open
but it is there for sem_init and etcs.
Thankzzzzzzz For Help
Much Appericiated
Gaurav
0
 
LVL 5

Expert Comment

by:garboua
ID: 6199123
did you ever do a  "man sem_open"  try it and it will learn more.
0
 

Author Comment

by:GauravN4U
ID: 6218502
yup garboua I did man sem_open and the page wont open.
But when I did "man sem_init" it shows me those functions ... except sem_opsn so I thought it isint supported. I am using Red HAt 7.0 system.

0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now