diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-02-22 13:43:48 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-02-22 13:56:02 -0500 |
| commit | 0cd89e9176ab36fc5e267120dc4d75cb79d32684 (patch) | |
| tree | c2109735be89fdaf86b55a95d98a4797d086217c /lib/std/os.zig | |
| parent | dca19b67573dc46260b318e9253370fbc628834d (diff) | |
| download | zig-0cd89e9176ab36fc5e267120dc4d75cb79d32684.tar.gz zig-0cd89e9176ab36fc5e267120dc4d75cb79d32684.zip | |
std.os.execvpeZ_expandArg0: fix not restoring argv[0]
This function expands argv[0] into the absolute path resolved with PATH
environment variable before making the execve syscall. However, in case
the execve fails, e.g. with ENOENT, it did not restore argv to how it
was before it was passed in. This resulted in the caller performing an
invalid free.
This commit also adds verbose debug info when native system C compiler
detection fails. See #4521.
Diffstat (limited to 'lib/std/os.zig')
| -rw-r--r-- | lib/std/os.zig | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index 0f492a25f2..766b678c46 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -955,6 +955,7 @@ pub const Arg0Expand = enum { /// Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable, /// and `argv[0]` is expanded to be the same absolute path that is passed to the execve syscall. +/// If this function returns with an error, `argv[0]` will be restored to the value it was when it was passed in. pub fn execvpeZ_expandArg0( comptime arg0_expand: Arg0Expand, file: [*:0]const u8, @@ -972,6 +973,14 @@ pub fn execvpeZ_expandArg0( var it = mem.tokenize(PATH, ":"); var seen_eacces = false; var err: ExecveError = undefined; + + // In case of expanding arg0 we must put it back if we return with an error. + const prev_arg0 = child_argv[0]; + defer switch (arg0_expand) { + .expand => child_argv[0] = prev_arg0, + .no_expand => {}, + }; + while (it.next()) |search_path| { if (path_buf.len < search_path.len + file_slice.len + 1) return error.NameTooLong; mem.copy(u8, &path_buf, search_path); |
