From cb0fcf545c8d61be64a85666eb5190406c619b0f Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Sat, 27 Jan 2024 22:56:40 -0800 Subject: [PATCH] wip --- src/bun.js/api/bun/process.zig | 85 +++++++++++++++++++++++++++++++--- src/deps/libuv.zig | 12 +++-- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/bun.js/api/bun/process.zig b/src/bun.js/api/bun/process.zig index c6f4e235ed..123f336490 100644 --- a/src/bun.js/api/bun/process.zig +++ b/src/bun.js/api/bun/process.zig @@ -456,7 +456,7 @@ pub const Process = struct { pub fn hasRef(this: *Process) bool { return switch (this.poller) { - .fd => this.poller.fd.canEnableKeepingProcessAlive(), + .fd => this.poller.fd.isActive(), .uv => if (Environment.isWindows) this.poller.uv.hasRef() else unreachable, .waiter_thread => this.poller.waiter_thread.isActive(), else => false, @@ -791,8 +791,37 @@ pub const PosixSpawnOptions = struct { stdout: Stdio = .ignore, stderr: Stdio = .ignore, extra_fds: []const Stdio = &.{}, - cwd: []const u8 = "", + cwd: [:0]const u8 = "", detached: bool = false, + windows: void = {}, + + pub const Stdio = union(enum) { + path: []const u8, + inherit: void, + ignore: void, + buffer: void, + pipe: bun.FileDescriptor, + }; +}; + +pub const WindowsSpawnResult = struct { + +}; + +pub const WindowsSpawnOptions = struct { + stdin: Stdio = .ignore, + stdout: Stdio = .ignore, + stderr: Stdio = .ignore, + extra_fds: []const Stdio = &.{}, + cwd: [:0]const u8 = "", + detached: bool = false, + windows: WindowsOptions = .{}, + + pub const WindowsOptions = struct { + verbatim_arguments: bool = false, + hide_window: bool = false, + loop: *bun.windows.libuv.Loop = undefined, + }; pub const Stdio = union(enum) { path: []const u8, @@ -811,6 +840,18 @@ pub const PosixSpawnResult = struct { stderr: ?bun.FileDescriptor = null, extra_pipes: std.ArrayList(bun.FileDescriptor) = std.ArrayList(bun.FileDescriptor).init(bun.default_allocator), + pub fn toProcess( + this: *const PosixSpawnResult, + event_loop: anytype, + sync: bool, + ) *Process { + return Process.initPosix( + this.*, + event_loop, + sync, + ); + } + fn pidfdFlagsForLinux() u32 { const kernel = @import("../../../analytics.zig").GenerateHeader.GeneratePlatform.kernelVersion(); @@ -871,12 +912,13 @@ pub const PosixSpawnResult = struct { unreachable; } }; -pub const SpawnOptions = if (Environment.isPosix) PosixSpawnOptions else void; -pub fn spawnProcess( +pub const SpawnOptions = if (Environment.isPosix) PosixSpawnOptions else WindowsSpawnOptions; +pub const spawnProcess = if (Environment.isPosix) spawnProcessPosix else spawnProcessWin32; +pub fn spawnProcessPosix( options: *const PosixSpawnOptions, argv: [*:null]?[*:0]const u8, envp: [*:null]?[*:0]const u8, -) !PosixSpawnResult { +) !JSC.Maybe(PosixSpawnResult) { var actions = try PosixSpawn.Actions.init(); defer actions.deinit(); @@ -1014,7 +1056,7 @@ pub fn spawnProcess( switch (spawn_result) { .err => { - _ = try spawn_result.unwrap(); // trigger the error + return .{ .err = spawn_result.err }; }, .result => |pid| { spawned.pid = pid; @@ -1030,13 +1072,42 @@ pub fn spawnProcess( } } - return spawned; + return .{ .result = spawned }; }, } unreachable; } +pub fn spawnProcessWin32( + options: *const WindowsSpawnOptions, + argv: [*:null]?[*:0]const u8, + envp: [*:null]?[*:0]const u8, +) JSC.Maybe(WindowsSpawnResult) { + var uv_process_options = std.mem.zeroes(uv.uv_process_options_t); + uv_process_options.cwd = options.cwd; + uv_process_options.args = argv; + uv_process_options.env = envp; + uv_process_options.file = argv[0].?; + uv_process_options.exit_cb = &Process.onExitUV; + + if (options.windows.hide_window) { + uv_process_options.flags |= uv.uv_process_flags.UV_PROCESS_WINDOWS_HIDE; + } + + if (options.windows.verbatim_arguments) { + uv_process_options.flags |= uv.uv_process_flags.UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; + } + + if (options.detached) { + uv_process_options.flags |= uv.uv_process_flags.UV_PROCESS_DETACHED; + } + + var stdio_options = std.mem.zeroes([3]uv.uv_stdio_container_t); + + +} + // pub const TaskProcess = struct { // process: *Process, // pending_error: ?bun.sys.Error = null, diff --git a/src/deps/libuv.zig b/src/deps/libuv.zig index 5093df3368..f91137bd7c 100644 --- a/src/deps/libuv.zig +++ b/src/deps/libuv.zig @@ -303,7 +303,7 @@ pub const uv_pipe_s = struct_uv_pipe_s; pub const uv_tty_s = struct_uv_tty_s; pub const uv_poll_s = struct_uv_poll_s; pub const uv_process_exit_s = struct_uv_process_exit_s; -pub const uv_process_s = uv_process; +pub const uv_process_s = Process; pub const uv_fs_event_req_s = struct_uv_fs_event_req_s; pub const uv_fs_event_s = struct_uv_fs_event_s; pub const uv_fs_poll_s = struct_uv_fs_poll_s; @@ -1318,7 +1318,7 @@ const union_unnamed_424 = extern union { fd: c_int, reserved: [4]?*anyopaque, }; -pub const uv_process_t = uv_process; +pub const uv_process_t = Process; pub const uv_exit_cb = ?*const fn (*uv_process_t, i64, c_int) callconv(.C) void; const struct_unnamed_426 = extern struct { overlapped: OVERLAPPED, @@ -1341,7 +1341,7 @@ pub const struct_uv_process_exit_s = extern struct { u: union_unnamed_425, next_req: [*c]struct_uv_req_s, }; -pub const uv_process = extern struct { +pub const Process = extern struct { data: ?*anyopaque, loop: *uv_loop_t, type: uv_handle_type, @@ -1350,7 +1350,7 @@ pub const uv_process = extern struct { u: union_unnamed_424, endgame_next: [*c]uv_handle_t, flags: c_uint, - exit_cb: ?*const fn ([*c]uv_process, i64, c_int) callconv(.C) void, + exit_cb: ?*const fn ([*c]Process, i64, c_int) callconv(.C) void, pid: c_int, exit_req: struct_uv_process_exit_s, unused: ?*anyopaque, @@ -1359,6 +1359,10 @@ pub const uv_process = extern struct { process_handle: HANDLE, exit_cb_pending: u8, + pub fn spawn(handle: *uv_process_t, loop: *uv_loop_t, options: *const uv_process_options_t) ReturnCode { + return uv_spawn(loop, handle, options); + } + pub usingnamespace HandleMixin(@This()); pub fn kill(this: *@This(), signum: c_int) ReturnCode {