C++ How to get a filename (and path) of the executing .so module in Unix?
Something similar to GetModuleFileName on Windows.
C++ How to get a filename (and path) of the executing .so module in Unix?
Something similar to GetModuleFileName on Windows.
Unfortunately, there is no way to do that using UNIX or POSIX. If you need to use it to look up some sort of data, you should use the $PATH environment variable and search for the data in a path that is relative to each entry in $PATH. For example, it is not uncommon to store binaries in "installdir/bin" for some installation directory "installdir" and to store the associated data in "installdir/share/name_of_program" for some installation directory and some program named "name_of_program". If that is the case, then looking at "../share/name_of_program/name_of_resource_file" relative to each entry in getenv("PATH") is a good way of searching for resources. Another thing you could do is allow the necessary information to be provided on the commandline or in some configuration file, and only perform the search if needed as a fallback option.
Edit
Now that you've stated your rationale for this, I would advise you to simply use the QSettings class from Qt for your configuration information, as it uses the preferred native mechanism for each platform (the registry on Windows, a PLIST file on Mac OS X, the Gnome GConf database on Linux). You may want to take a look at my C++ Project Template as it uses Qt to do just this, and it provides simple commandline options to easily tweak the configuration settings ("--prefset", "--prefget", and "--preflist" manipulate QSettings).
That said, if you absolutely must use an XML configuration file of your own instead of using the preferred native mechanism, I strongly advise you to place the system-wide configuration in "installdir/etc" while placing your library in "installdir/lib" for some installation directory "installdir", as that is the typical place for configuration files on UNIX systems, and "installdir/lib" should ONLY be used for library files, not for configuration files and other errata. I suggest you place a user-specific version of the configuration file in "$XDG_CONFIG_HOME" (if it is defined) or in "$HOME/.config" (where "$HOME" is the user's home folder).
When searching for the system-wide configuration file, I would recommend that you search within $XDG_CONFIG_DIRS if it is defined; if it isn't defined, then falling back to "/etc/xdg" or searching for "../etc/name_of_your_program.conf.xml" relative to "$PATH" and possibly also relative to the "$LD_LIBRARY_PATH", "$DYLD_LIBRARY_PATH", "$DYLD_FALLBACK_LIBRARY_PATH"), the contents of "/etc/ld.so.conf" if it exists, and the contents of "/etc/ld.so.conf.d/*.conf" if those files exist, halting your search as soon as you encounter the first valid such configuration file would be a sensible approach.
Credit goes to Roger for pointing out the XDG Basedir Spec and for his excellent constructive criticisms.
Possible solutions:
/proc/{PID}/mmap
file for the list of shared libraries. Where {PID} is the process pid (you can get it using getpid()
).ldd
for the program binary file (stored in argv[0]
).ldd
commands source code from uClibc
how to get the list of shared libs from an elf binary.Although it is not a POSIX standard interface, the dladdr()
function is available on many systems including Linux, Solaris, Darwin/Mac OS X, FreeBSD, HP-UX, IRIX, and AIX. This function takes an address, which could be a pointer to a static function within the module for example (if cast to void *
), and fills in a Dl_info
structure with information including the path name of the shared object containing that address (in the dli_fname
member).