mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:24:33 +01:00
std.Io.Threaded: implement processReplace
This commit is contained in:
parent
08cc9e8d59
commit
baa49e5929
2 changed files with 40 additions and 24 deletions
|
|
@ -1122,6 +1122,7 @@ const Syscall = struct {
|
|||
|
||||
const max_iovecs_len = 8;
|
||||
const splat_buffer_size = 64;
|
||||
const default_PATH = "/usr/local/bin:/bin/:/usr/bin";
|
||||
|
||||
comptime {
|
||||
if (@TypeOf(posix.IOV_MAX) != void) assert(max_iovecs_len <= posix.IOV_MAX);
|
||||
|
|
@ -12765,12 +12766,37 @@ fn scanEnviron(t: *Threaded) void {
|
|||
}
|
||||
|
||||
fn processReplace(userdata: ?*anyopaque, options: process.ReplaceOptions) process.ReplaceError {
|
||||
_ = userdata;
|
||||
_ = options;
|
||||
@panic("TODO processReplace");
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
|
||||
if (!process.can_replace) return error.OperationUnsupported;
|
||||
|
||||
t.scanEnviron(); // for PATH
|
||||
const PATH = t.environ.string.PATH orelse default_PATH;
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(t.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const argv_buf = try arena.allocSentinel(?[*:0]const u8, options.argv.len, null);
|
||||
for (options.argv, 0..) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr;
|
||||
|
||||
const envp: [*:null]const ?[*:0]const u8 = m: {
|
||||
const prog_fd: i32 = -1;
|
||||
if (options.environ_map) |environ_map| {
|
||||
break :m (try environ_map.createBlockPosix(arena, .{
|
||||
.zig_progress_fd = prog_fd,
|
||||
})).ptr;
|
||||
}
|
||||
break :m (try process.Environ.createBlockPosix(t.environ.process_environ, arena, .{
|
||||
.zig_progress_fd = prog_fd,
|
||||
})).ptr;
|
||||
};
|
||||
|
||||
return posixExecv(options.expand_arg0, argv_buf.ptr[0].?, argv_buf.ptr, envp, PATH);
|
||||
}
|
||||
|
||||
fn processReplacePath(userdata: ?*anyopaque, dir: Dir, options: process.ReplaceOptions) process.ReplaceError {
|
||||
if (!process.can_replace) return error.OperationUnsupported;
|
||||
_ = userdata;
|
||||
_ = dir;
|
||||
_ = options;
|
||||
|
|
@ -12778,6 +12804,7 @@ fn processReplacePath(userdata: ?*anyopaque, dir: Dir, options: process.ReplaceO
|
|||
}
|
||||
|
||||
fn processSpawnPath(userdata: ?*anyopaque, dir: Dir, options: process.SpawnOptions) process.SpawnError!process.Child {
|
||||
if (!process.can_spawn) return error.OperationUnsupported;
|
||||
_ = userdata;
|
||||
_ = dir;
|
||||
_ = options;
|
||||
|
|
@ -12903,7 +12930,7 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp
|
|||
errdefer destroyPipe(err_pipe);
|
||||
|
||||
t.scanEnviron(); // for PATH
|
||||
const PATH = t.environ.string.PATH orelse "/usr/local/bin:/bin/:/usr/bin";
|
||||
const PATH = t.environ.string.PATH orelse default_PATH;
|
||||
|
||||
const pid_result = try posix.fork();
|
||||
if (pid_result == 0) {
|
||||
|
|
@ -12954,7 +12981,7 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp
|
|||
}
|
||||
}
|
||||
|
||||
const err = execvpeZ_expandArg0(options.expand_arg0, argv_buf.ptr[0].?, argv_buf.ptr, envp, PATH);
|
||||
const err = posixExecv(options.expand_arg0, argv_buf.ptr[0].?, argv_buf.ptr, envp, PATH);
|
||||
forkBail(err_pipe[1], err);
|
||||
}
|
||||
|
||||
|
|
@ -14361,7 +14388,7 @@ fn testArgvToCommandLineWindows(argv: []const []const u8, expected_cmd_line: []c
|
|||
try std.testing.expectEqualStrings(expected_cmd_line, cmd_line);
|
||||
}
|
||||
|
||||
fn execvpeZ_expandArg0(
|
||||
fn posixExecv(
|
||||
arg0_expand: process.ArgExpansion,
|
||||
file: [*:0]const u8,
|
||||
child_argv: [*:null]?[*:0]const u8,
|
||||
|
|
@ -14369,10 +14396,10 @@ fn execvpeZ_expandArg0(
|
|||
PATH: []const u8,
|
||||
) process.ReplaceError {
|
||||
const file_slice = std.mem.sliceTo(file, 0);
|
||||
if (std.mem.findScalar(u8, file_slice, '/') != null) return execveZ(file, child_argv, envp);
|
||||
if (std.mem.findScalar(u8, file_slice, '/') != null) return posixExecvPath(file, child_argv, envp);
|
||||
|
||||
// Use of PATH_MAX here is valid as the path_buf will be passed
|
||||
// directly to the operating system in execveZ.
|
||||
// directly to the operating system in posixExecvPath.
|
||||
var path_buf: [posix.PATH_MAX]u8 = undefined;
|
||||
var it = std.mem.tokenizeScalar(u8, PATH, ':');
|
||||
var seen_eacces = false;
|
||||
|
|
@ -14397,7 +14424,7 @@ fn execvpeZ_expandArg0(
|
|||
.expand => child_argv[0] = full_path,
|
||||
.no_expand => {},
|
||||
}
|
||||
err = execveZ(full_path, child_argv, envp);
|
||||
err = posixExecvPath(full_path, child_argv, envp);
|
||||
switch (err) {
|
||||
error.AccessDenied => seen_eacces = true,
|
||||
error.FileNotFound, error.NotDir => {},
|
||||
|
|
@ -14408,8 +14435,8 @@ fn execvpeZ_expandArg0(
|
|||
return err;
|
||||
}
|
||||
|
||||
/// This function ignores PATH environment variable. See `execvpeZ` for that.
|
||||
pub fn execveZ(
|
||||
/// This function ignores PATH environment variable.
|
||||
pub fn posixExecvPath(
|
||||
path: [*:0]const u8,
|
||||
child_argv: [*:null]const ?[*:0]const u8,
|
||||
envp: [*:null]const ?[*:0]const u8,
|
||||
|
|
@ -14447,17 +14474,6 @@ pub fn execveZ(
|
|||
}
|
||||
}
|
||||
|
||||
/// This function also uses the PATH environment variable to get the full path to the executable.
|
||||
/// If `file` is an absolute path, this is the same as `execveZ`.
|
||||
pub fn execvpeZ(
|
||||
file: [*:0]const u8,
|
||||
argv_ptr: [*:null]const ?[*:0]const u8,
|
||||
envp: [*:null]const ?[*:0]const u8,
|
||||
PATH: []const u8,
|
||||
) process.ReplaceError {
|
||||
return execvpeZ_expandArg0(.no_expand, file, argv_ptr, envp, PATH);
|
||||
}
|
||||
|
||||
fn windowsMakePipeIn(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const windows.SECURITY_ATTRIBUTES) !void {
|
||||
var rd_h: windows.HANDLE = undefined;
|
||||
var wr_h: windows.HANDLE = undefined;
|
||||
|
|
|
|||
|
|
@ -288,11 +288,11 @@ pub const ReplaceError = error{
|
|||
FileBusy,
|
||||
ProcessFdQuotaExceeded,
|
||||
SystemFdQuotaExceeded,
|
||||
} || Io.Dir.PathNameError || Io.Cancelable || Io.UnexpectedError;
|
||||
} || Allocator.Error || Io.Dir.PathNameError || Io.Cancelable || Io.UnexpectedError;
|
||||
|
||||
pub const ReplaceOptions = struct {
|
||||
argv: []const []const u8,
|
||||
arg0_expand: ArgExpansion = .no_expand,
|
||||
expand_arg0: ArgExpansion = .no_expand,
|
||||
/// Replaces the environment when provided. The PATH value from here is
|
||||
/// never used to resolve `argv[0]`.
|
||||
environ_map: ?*const Environ.Map = null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue