私が試してみました:
char *path = realpath(getenv("_"), NULL);
*(strrchr(path, '/')+1) = '\0';
それは機能しますが、実行可能ファイルが親プロセスによって呼び出されると、親プロセスのパスが表示されます。
私はたくさんグーグルで検索しましたが、適切に機能するソリューションを見つけることができませんでした。
/proc
オプションはありません。
いくつかの実験の後、実用的な解決策があると思います...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
const char *getExecutablePath(char *epath) {
int mib[4];
char **argv;
size_t len;
const char *comm;
int ok = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC_ARGS;
mib[2] = getpid();
mib[3] = KERN_PROC_ARGV;
if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0)
abort();
if (!(argv = malloc(len)))
abort();
if (sysctl(mib, 4, argv, &len, NULL, 0) < 0)
abort();
comm = argv[0];
if (*comm == '/' || *comm == '.') {
if (realpath(comm, epath))
ok = 1;
} else {
char *sp;
char *xpath = strdup(getenv("PATH"));
char *path = strtok_r(xpath, ":", &sp);
struct stat st;
if (!xpath)
abort();
while (path) {
snprintf(epath, PATH_MAX, "%s/%s", path, comm);
if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) {
ok = 1;
break;
}
path = strtok_r(NULL, ":", &sp);
}
free(xpath);
}
if (ok)
*strrchr(epath, '/') = '\0';
free(argv);
return ok ? epath : NULL;
}
int main(void) {
char path[PATH_MAX];
if (getExecutablePath(path))
puts(path);
return 0;
}