1

POSIX 2008 introduces several file system functions, which rely on directory descriptor when determining a path to the file (I'm speaking about -at functions, such as openat, renameat, symlinkat, etc.). I doubt if all POSIX platforms support it (well, at least the most recent versions seem to support) and I'm looking for a way to determine if platform supports such functions. Of course one may use autoconf and friends for compile-time determination, but I'm looking for a possibility to find out whether implementation supports -at functions dynamically.

The first that comes to my mind is a dlopen()/dlsym()/dlclose() combo; at least I've successfully loaded the necessary symbols from /usr/libc.so.6 shared library. However, libc may be (or is?) named differently on various platforms. Is there a list of standard locations to find libc? At least on Linux /lib/libc.so appears to be not a symbolic link to shared library, but a ld script. May be there exist some other way to examine during runtime if a POSIX function is supported? Thanks in advance!

1 Answer 1

4
#define _GNU_SOURCE 1 #include <dlfcn.h> #include <stdio.h> int main () { void * funcaddr = dlsym(RTLD_DEFAULT, "symlinkat"); /* -----------------------^ magic! */ printf ("funcaddr = %p\n", funcaddr); } 

Output:

funcaddr = 0x7fb62e44c2c0 

Magic explanation: your program is already linked with libc, no need to load it again.

Note, this is actually GNU libc feature, as hinted by _GNU_SOURCE. POSIX reserves RTLD_DEFAULT "for future use", and then proceeds to define it exactly like GNU libc does. So strictly speaking it is not guaranteed to work on all POSIX systems.

Sign up to request clarification or add additional context in comments.

4 Comments

Heck, I thought that answer would be simple but could not even imagine that it will be such simple! Now I've realized that even Windows has GetModuleHandleW(NULL), which provides the same thing. Thank you very much!
P.S. I couldn't manage to get it work with either C4Droid or CCTools on Android. Since Android is partially POSIX-compatible, I guess that such behaviour may be a bug or an unimplemented feature.
Oops, you've changed NULL to RTLD_DEFAULT. Everything works now. Thank you very much!
This is actually GNU libc feature, as hinted by _GNU_SOURCE. POSIX reserves RTLD_DEFAULT "for future use", so strictly speaking it is not guaranteed to work on all POSIX systems.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.