Finding current executable's path without /pro

2018-12-31 05:38发布

It seems to me that Linux has it easy with /proc/self/exe. But I'd like to know if there is a convenient way to find the current application's directory in C/C++ with cross-platform interfaces. I've seen some projects mucking around with argv[0], but it doesn't seem entirely reliable.

If you ever had to support, say, Mac OS X, which doesn't have /proc/, what would you have done? Use #ifdefs to isolate the platform-specific code (NSBundle, for example)? Or try to deduce the executable's path from argv[0], $PATH and whatnot, risking finding bugs in edge cases?

12条回答
骚的不知所云
2楼-- · 2018-12-31 06:00

If you use C, you can use the getwd function:

int main()
{       
 char buf[4096];
 getwd(buf);
 printf(buf);
}

This will you print on the standard output, the current directory of the executable.

查看更多
其实,你不懂
3楼-- · 2018-12-31 06:00

The absolute value path of a program is in the PWD of the envp of your main function, also there's a function in C called getenv, so there's that.

查看更多
明月照影归
4楼-- · 2018-12-31 06:04

Some OS-specific interfaces:

The portable (but less reliable) method is to use argv[0]. Although it could be set to anything by the calling program, by convention it is set to either a path name of the executable or a name that was found using $PATH.

Some shells, including bash and ksh, set the environment variable "_" to the full path of the executable before it is executed. In that case you can use getenv("_") to get it. However this is unreliable because not all shells do this, and it could be set to anything or be left over from a parent process which did not change it before executing your program.

查看更多
还给你的自由
5楼-- · 2018-12-31 06:04

You can use argv[0] and analyze the PATH environment variable. Look at : A sample of a program that can find itself

查看更多
何处买醉
6楼-- · 2018-12-31 06:06

If you ever had to support, say, Mac OS X, which doesn't have /proc/, what would you have done? Use #ifdefs to isolate the platform-specific code (NSBundle, for example)?

Yes isolating platform specific code with #ifdefs is the conventional way this is done.

Another approach would be to have a have clean #ifdef-less header wich contains function declarations and put the implementations in platform specific source files. For example, check out how Poco C++ library does something similar for their Environment class.

查看更多
唯独是你
7楼-- · 2018-12-31 06:08

Depending on the version of QNX Neutrino, there are different ways to find the full path and name of the executable file that was used to start the running process. I denote the process identifier as <PID>. Try the following:

  1. If the file /proc/self/exefile exists, then its contents are the requested information.
  2. If the file /proc/<PID>/exefile exists, then its contents are the requested information.
  3. If the file /proc/self/as exists, then:
    1. open() the file.
    2. Allocate a buffer of, at least, sizeof(procfs_debuginfo) + _POSIX_PATH_MAX.
    3. Give that buffer as input to devctl(fd, DCMD_PROC_MAPDEBUG_BASE,....
    4. Cast the buffer to a procfs_debuginfo*.
    5. The requested information is at the path field of the procfs_debuginfo structure. Warning: For some reason, sometimes, QNX omits the first slash / of the file path. Prepend that / when needed.
    6. Clean up (close the file, free the buffer, etc.).
  4. Try the procedure in 3. with the file /proc/<PID>/as.
  5. Try dladdr(dlsym(RTLD_DEFAULT, "main"), &dlinfo) where dlinfo is a Dl_info structure whose dli_fname might contain the requested information.

I hope this helps.

查看更多
登录 后发表回答