ric*_*chq 16
完全不可移植的Linux解决方案:
#include <stdio.h>
#include <unistd.h>
int main()
{
char buffer[BUFSIZ];
readlink("/proc/self/exe", buffer, BUFSIZ);
printf("%s\n", buffer);
}
Run Code Online (Sandbox Code Playgroud)
这使用"/ proc/self"技巧,它指向正在运行的进程.这样就省去了查找PID的麻烦.错误处理作为练习留给警惕.
非便携式Windows解决方案:
WCHAR path[MAX_PATH];
GetModuleFileName(NULL, path, ARRAYSIZE(path));
Run Code Online (Sandbox Code Playgroud)
这是一个可能对Linux系统有帮助的示例:
/*
* getexename - Get the filename of the currently running executable
*
* The getexename() function copies an absolute filename of the currently
* running executable to the array pointed to by buf, which is of length size.
*
* If the filename would require a buffer longer than size elements, NULL is
* returned, and errno is set to ERANGE; an application should check for this
* error, and allocate a larger buffer if necessary.
*
* Return value:
* NULL on failure, with errno set accordingly, and buf on success. The
* contents of the array pointed to by buf is undefined on error.
*
* Notes:
* This function is tested on Linux only. It relies on information supplied by
* the /proc file system.
* The returned filename points to the final executable loaded by the execve()
* system call. In the case of scripts, the filename points to the script
* handler, not to the script.
* The filename returned points to the actual exectuable and not a symlink.
*
*/
char* getexename(char* buf, size_t size)
{
char linkname[64]; /* /proc/<pid>/exe */
pid_t pid;
int ret;
/* Get our PID and build the name of the link in /proc */
pid = getpid();
if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", pid) < 0)
{
/* This should only happen on large word systems. I'm not sure
what the proper response is here.
Since it really is an assert-like condition, aborting the
program seems to be in order. */
abort();
}
/* Now read the symbolic link */
ret = readlink(linkname, buf, size);
/* In case of an error, leave the handling up to the caller */
if (ret == -1)
return NULL;
/* Report insufficient buffer size */
if (ret >= size)
{
errno = ERANGE;
return NULL;
}
/* Ensure proper NUL termination */
buf[ret] = 0;
return buf;
}
Run Code Online (Sandbox Code Playgroud)
基本上,您getpid()用来查找PID,然后找出/proc/<pid>/exe指向的符号链接.
小智 5
我使用的一个技巧,至少在OS X和Linux上解决$ PATH问题,是制作"真正的二进制" foo.exe而不是foo:文件foo,这是用户实际调用的,是一个存根shell用原始参数调用函数的脚本.
#!/bin/sh
$0.exe "$@"
Run Code Online (Sandbox Code Playgroud)
通过shell脚本重定向意味着真正的程序获得了一个argv[0]实际上有用的程序,而不是可能存在于程序中的程序$PATH.我从标准ML编程的角度写了一篇关于这个的博客文章,之前我发现这可能是一个与语言无关的问题.