View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001992 | 1003.1(2024)/Issue8 | System Interfaces | public | 2026-07-14 16:14 | 2026-07-21 02:06 |
| Reporter | kasperk81 | Assigned To | |||
| Priority | normal | Severity | Editorial | Type | Enhancement Request |
| Status | New | Resolution | Open | ||
| Name | Kasper K. | ||||
| Organization | Independent | ||||
| User Reference | |||||
| Section | XSH 3 | ||||
| Page Number | unknown | ||||
| Line Number | unknown | ||||
| Interp Status | |||||
| Final Accepted Text | |||||
| Summary | 0001992: Add getexepath() to retrieve the absolute pathname of the current process executable image. | ||||
| Description | There is currently no standardized, portable mechanism in POSIX to retrieve the absolute pathname of the executable file currently executing the calling process. Runtimes, language interpreters, and asset loaders must resort to highly unportable, platform-specific mechanisms. - Linux relies on parsing the "/proc/self/exe" symlink or using `getauxval(AT_EXECFN)`. - FreeBSD and NetBSD use a sysctl interface via KERN_PROC_PATHNAME. - SunOS implements getexecname(). - macOS implements a non-POSIX _NSGetExecutablePath() function. Others like OpenBSD force us to rely on argv[0] and (if the process didn't start with an absolute path) scanning the PATH environment variable, which is fundamentally unsafe and unreliable (someone else in the PATH with the same name appearing early is picked up). Furthermore, the parent process can easily manipulate or empty argv and envp during an execve() call, leaving the child completely unable to safely determine its own physical location. Adding a native, safe API to POSIX eliminates immense cross-platform boilerplate across programming frameworks and toolchains that require explicit binary path auditing. | ||||
| Desired Action | 1. In <unistd.h>, add the following function prototype: ssize_t getexepath(char *buf, size_t bufsize); 2. Add a new manual page under Section 3 (FUNCTIONS) detailing the specification: NAME getexepath — get the absolute pathname of the executing process image. SYNOPSIS #include <unistd.h> ssize_t getexepath(char *buf, size_t bufsize); DESCRIPTION The getexepath() function shall copy an absolute pathname of the executable file associated with the current process into the buffer pointed to by buf, which has a size of bufsize. If the actual length of the pathname (including the terminating null byte) is greater than bufsize, the string shall be truncated to bufsize - 1 bytes and null-terminated. RETURN VALUE Upon successful completion, getexepath() shall return the number of bytes required to hold the full, non-truncated path (excluding the terminating null byte). If an error occurs, -1 shall be returned and errno set to indicate the error. ERRORS The getexepath() function shall fail if: [EINVAL] - The buf argument is a null pointer. [ENOENT] - The executable file has been unlinked from the filesystem and the system cannot resolve its original path. | ||||
| Tags | api, enhancement, issue9, process, unistd | ||||
|
|
When the program has an interpreter, e,g, by starting with "#!", should this return the path of the program, or the path of its interpreter? How do you define "interpreter"? Keep in mind that some systems require an interpreter for some types of binaries; e.g. Linux x86_64 has /lib64/ld-linux-x86-64.so.2 to load ELF binaries. |
|
|
What Problem Is This Trying To Solve? It is my understanding that the programs looking for this info are a) looking for the _directory path_ that contains the executed program (so they can create other paths relative to that, ala ELF $ORIGIN), AND b) would be utterly happy to ERROR OUT if the path by which it had been accessed had been moved or removed between when they were executed and when they asked for this info. Do you, kasperk81, agree or disagree? If you disagree, can you describe how the information from this call will be used, and/or what should be done in the latter cases? Next up: what's the expected behavior when fexecve() was used? That the system merely remember the series of references that were used to get to the file that was openat()ed before the call to fexecve(), regardless of intervening renames? |
|
|
> When the program has an interpreter, e,g, by starting with "#!", should this return the path of the program, or the path of its interpreter? For a #! interpreter, it should return the path of the interpreter. If programs written in the interpreted language want to determine *their* path, that would presumably be done with a language or language-library function, which the interpreter would implement. > Keep in mind that some systems require an interpreter for some types of binaries; e.g. Linux x86_64 has /lib64/ld-linux-x86-64.so.2 to load ELF binaries. Most if not all systems using ELF start dynamically-loaded binaries by running the run-time linker; that's not specific to Linux or Linux on x86-64. The SunOS referred to in the original post is presumably SunOS 5, a/k/a "the core OS part of Solaris 2 and up", which uses ELF and starts dynamically-loaded binaries by running the run-time linker; in that case, getexecname() returns the path to the program run by the run-time linker, not to the path of the run-time linker. macOS (and other Darwin-based OSes) are similar. But that's not the *program* that's really running; once the run-time linker has called the program at its startup address (normally the address of main()), it's just there to handle dlopen(), dlsym(), and company. it's not really an "interpreter" in the sense of a shell or a scripting language interpreter. |
|
|
> It is my understanding that the programs looking for this info are > a) looking for the _directory path_ that contains the executed program (so they can create other paths relative to that, ala ELF $ORIGIN), AND > b) would be utterly happy to ERROR OUT if the path by which it had been accessed had been moved or removed between when they were executed and when they asked for this info. As a core developer on a program that looks for that info (Wireshark): a) Wireshark does that because, in some cases, it uses the path of a directory above the executable to find various data files etc. that it uses, AND b) for better or worse, it will probably have problems if the program *and* all the relevant files were moved after that, so, as the saying goes "Doctor, it hurts when I do this!" "OK, so don't do that!". (If the program is moved after it fetches the executable path, but the other files *aren't* moved, things will work - it only fetches the path once and remembers it after that.) |
|
|
I provided two examples as an obvious contrast, but the real question is whether there is consensus on where exactly the line lies between those extremes should be. Some other examples, by no means comprehensive: · an interpreter for a synthetic byte code such as Dalvik or Python (pyc); · a JIT compiler that produces native byte code and runs it; · an emulator for a different CPU, including ELF loading; · an emulator in hardware (e.g. x86 on Apple Rosetta); · an emulator for a different OS (e.g. Wine); The point isn't to make a choice for each of these; rather the point is to explain the rationale that leads to your preferred choices. > [ld-linux .. is] not really an "interpreter" in the sense of a shell or a scripting language interpreter. For a standard that distinction needs a a formal definition, not just a "sense". Or we just leave it unspecified which path is returned, but I suspect many would find that highly unsatisfactory. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-07-14 16:14 | kasperk81 | New Issue | |
| 2026-07-14 16:14 | kasperk81 | Tag Attached: api | |
| 2026-07-14 16:14 | kasperk81 | Tag Attached: enhancement | |
| 2026-07-14 16:14 | kasperk81 | Tag Attached: process | |
| 2026-07-14 16:14 | kasperk81 | Tag Attached: unistd | |
| 2026-07-20 02:02 | m.kealey | Note Added: 0007453 | |
| 2026-07-20 02:15 | m.kealey | Note Edited: 0007453 | |
| 2026-07-20 06:48 | philip-guenther | Note Added: 0007454 | |
| 2026-07-20 07:01 | Guy Harris | Note Added: 0007455 | |
| 2026-07-20 07:19 | Guy Harris | Note Added: 0007456 | |
| 2026-07-20 15:15 | msbrown | Tag Attached: issue9 | |
| 2026-07-20 17:47 | m.kealey | Note Added: 0007460 | |
| 2026-07-21 02:01 | m.kealey | Note Edited: 0007460 | |
| 2026-07-21 02:04 | m.kealey | Note Edited: 0007460 | |
| 2026-07-21 02:04 | m.kealey | Note Edited: 0007460 | |
| 2026-07-21 02:06 | m.kealey | Note Edited: 0007460 |