View Issue Details

IDProjectCategoryView StatusLast Update
00019921003.1(2024)/Issue8System Interfacespublic2026-07-21 02:06
Reporterkasperk81 Assigned To 
PrioritynormalSeverityEditorialTypeEnhancement Request
Status NewResolutionOpen 
NameKasper K.
OrganizationIndependent
User Reference
SectionXSH 3
Page Numberunknown
Line Numberunknown
Interp Status
Final Accepted Text
Summary0001992: Add getexepath() to retrieve the absolute pathname of the current process executable image.
DescriptionThere 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 Action1. 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.
Tagsapi, enhancement, issue9, process, unistd

Activities

m.kealey

2026-07-20 02:02

reporter   bugnote:0007453

Last edited: 2026-07-20 02:15

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.

philip-guenther

2026-07-20 06:48

reporter   bugnote:0007454

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?

Guy Harris

2026-07-20 07:01

reporter   bugnote:0007455

> 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.

Guy Harris

2026-07-20 07:19

reporter   bugnote:0007456

> 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.)

m.kealey

2026-07-20 17:47

reporter   bugnote:0007460

Last edited: 2026-07-21 02:06

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.

Issue History

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