views:

210

answers:

4

I have a C program which compiles and runs fine under Linux without any warnings, but when trying to compile it on SunOS, I get the following warning:

test.c: In function `my_function':
test.c:412: warning: implicit declaration of function `strerror_r'
Undefined                       first referenced
 symbol                             in file
strerror_r                          /var/tmp/ccRiPoGl.o
ld: fatal: Symbol referencing errors. No output written to test
collect2: ld returned 1 exit status
make: *** [test] Error 1

Any ideas?

A: 

Sounds like you need to give an extra hint to the linker to specify the library, it may not be in a standard path as is the case with Linux, if you know the name of the library, explicitly specify the library path as part of the CLI compiler when invoking gcc or equivalent under SunOS.

Here's an example of using a LIBS variable in a makefile.

LIBS = -L/usr/lib -L/usr/sys/lib -lsome_lib1 -lsome_lib2

Here's a line that is used to invoke the compiler in the makefile - notice the reference to the LIBS variable as I have shown in the above.

$(CC) -o $@ $(FILES) $(LIBS) $(CFLAGS)

Hope this helps, Best regards, Tom.

tommieb75
+1  A: 

It looks like strerror_r may not be available on that platform. I just checked on an old Solaris 2.8 box and strerror_r is not available.

It looks like you'll have to use strerror and deal with the occasional incorrect results due to the lack of thread safety.

R Samuel Klatchko
Wow, that's scary. I don't know how to deal with a function that lacks thread safety in a multi threaded program.
Jenna
Err.. or you could use locking to control access to the `strerror` function and *not* have to deal with incorrect results?
caf
+2  A: 

The "implicit declaration" warning is telling you that none of the headers you have #included have defined that function, and the "undefined symbol" warning is telling you that the function itself isn't defined in any of the libraries that you're linking in.

Taken together, this implies that C library you're compiling against doesn't provide the strerror_r function. You'll have to roll your own alternative.

For example, if you're using pthreads, you could do this:

int my_strerror_r(int errnum, char *buf, size_t buflen)
{
    static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;

    if (!buflen)
    {
        errno = ENOSPC;
        return -1;
    }

    buf[0] = 0;

    pthread_mutex_lock(&strerror_lock);
    strncat(buf, strerror(errnum), buflen - 1);
    pthread_mutex_unlock(&strerror_lock);

    return 0;
}
caf
anybody have any suggestions on how to "roll your own?"
Jenna
See my updated answer for one way of going about it.
caf
A Google search for "solaris strerror thread-safe" seems to indicate that strerror() is thread-safe on Solaris, but I didn't turn up an "official" statement of such.
Dewayne Christensen
In which case, you could just remove the pthreads locking in the above function and you'd be good to go.
caf
or maybe a preprocessor command which will remove the locks if it's being compiled on solaris
Jenna
Well, the locks are unlikely to be highly contended anyway - hopefully you're not bottlenecking on `strerror`!
caf
@caf, let's hope not! LOL
Jenna
A: 

Linux and SunOS are different operating systems and possibly have different implementations of the function you are using.

You might find the following article on POSIX compatibility by Dr. Bernstein at the University of Chicago at Illinois helpful:

http://cr.yp.to/docs/unixport.html

Good luck,

-bn

bn