View Issue Details

IDProjectCategoryView StatusLast Update
00020031003.1(2024)/Issue8System Interfacespublic2026-10-31 07:52
Reportertrevor.gross Assigned To 
PrioritynormalSeverityCommentTypeEnhancement Request
Status NewResolutionOpen 
NameTrevor Gross
Organization
User Reference
Sectionhttps://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html
Page Numberhttps://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html
Line Numberhttps://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html
Interp Status
Final Accepted Text
Summary0002003: Add execvpe()
DescriptionThere is currently no standard way to exec a process with path lookup, a MT-safe custom environment, and an arbitrary argument count. There are two close options:

1. Use execvp(), setting the parent's environment before calling and restoring upon failure. This may create races if other threads are running.
2. Use execle(). Use of variable arguments makes difficult for an unknown argument count.
Desired ActionStandardize execvpe(), providing the characteristics of execve() with a path lookup:

    int execvpe(const char *file, char *const argv[], char *const envp[]);

This already exists on some platforms:

1. Linux: https://linux.die.net/man/3/execvpe
2. Solaris: https://docs.oracle.com/cd/E88353_01/html/E37841/execvpe-2.html
3. QNX: https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.lib_ref/topic/e/execvpe.html
Tagsissue9

Activities

trevor.gross

2026-10-29 06:55

reporter   bugnote:0007535

Alternative: introduce one or both of the following, allowing use of execve().

    /* Look up a name in path, consistent with what is done in other libc
     * functions.
     */
    size_t posix_which(const char *file, char *buf, size_t len);

    /* Retrieve the path that should be used for lookups. Typically this is
     * getenv("PATH") if available, with a fallback to confstr(_CS_PATH).
     *
     * May point to environ, a static, or an initialized-once cache. Does
     * not need to be freed.
     */
    const char *posix_getpath();

steffen

2026-10-30 14:40

reporter   bugnote:0007536

What about posix_spawn()?

steffen

2026-10-30 15:10

reporter   bugnote:0007537

That is, .., i am not objecting as such, execvpe(2) is also on the BSDs. But there is a way, right?

lanodan

2026-10-30 17:11

manager   bugnote:0007538

I guess one issue is posix_spawn() creates another process, so would be unfit for software which chainloads to another program as done by env(1) and nohup(1) among quite few others.

That said I wonder if any of those would have multi-threading issues, one I'd more see is needing the environment to be unmodified for error-handling and fallbacks.

trevor.gross

2026-10-31 06:52

reporter   bugnote:0007539

The possible race is only applicable when replacing the current process. posix_spawn() has the right tools if the desire is a separate process, but even with fork+exec you can configure the child's environment as needed after forking.

Indeed replacing the process super common, but it's not impossible to hit in e.g. an interpreter. `exec echo hi` must set up child environment then exec() without forking; using a detached thread for any background task with env access is thus race-prone.

trevor.gross

2026-10-31 07:52

reporter   bugnote:0007540

execvpe() is the most common variant, but FreeBSD's internal execvPe() [1] and public execvP() [2] are also interesting because they make it possible to specify the search path. execvPe() would be especially nice for the shell case since those need to look up PATH from a shadow environment. I suppose that could also exist as posix_spawnattr_searchpath.

(Not sure why execvP() seems to error on NULL search_path, it would make sense to fall back to _PATH_DEFPATH.)

[1]: https://cgit.freebsd.org/src/tree/lib/libc/gen/exec.c?id=6d705f2bf17f2c221ffd0d9b0824ba0fb429392e#n247
[2]: https://man.freebsd.org/cgi/man.cgi?exec(3)

Issue History

Date Modified Username Field Change
2026-10-29 06:18 trevor.gross New Issue
2026-10-29 06:18 trevor.gross Tag Attached: issue9
2026-10-29 06:55 trevor.gross Note Added: 0007535
2026-10-30 14:40 steffen Note Added: 0007536
2026-10-30 15:10 steffen Note Added: 0007537
2026-10-30 17:11 lanodan Note Added: 0007538
2026-10-31 06:52 trevor.gross Note Added: 0007539
2026-10-31 07:52 trevor.gross Note Added: 0007540