public static Process Spawn(Loop loop, ProcessOptions options, Action<Process> exitCallback) { var process = new Process(loop, options, exitCallback); int r = uv_spawn(loop.NativeHandle, process.NativeHandle, ref process.process_options); Ensure.Success(r); return process; }
public static Process Spawn(Loop loop, ProcessOptions options, Action<Process, int, int> exitCallback) { Process process = new Process(loop); process.Stdin = new Pipe(loop, false); process.Stdout = new Pipe(loop, false); process.Stderr = new Pipe(loop, false); uv_process_options_t options_t = new uv_process_options_t(options, (exit_status, term_status) => { exitCallback(process, exit_status, term_status); // TODO: somehow dispose this // options_t.Dispose(); }); options_t.stdin_stream = process.Stdin.handle; options_t.stdout_stream = process.Stdout.handle; options_t.stderr_stream = process.Stderr.handle; int r = uv_spawn(loop.Handle, process.handle, options_t); Ensure.Success(r, loop); return process; }
public uv_process_options_t(Process process, ProcessOptions options) { if (string.IsNullOrEmpty(options.File)) { throw new ArgumentException("file of processoptions can't be null"); } else { file = Marshal.StringToHGlobalAnsi(options.File); } args = alloc(options.Arguments); env = alloc(options.Environment); cwd = Marshal.StringToHGlobalAnsi(options.CurrentWorkingDirectory); // all fields have to be set flags = 0; uid = 0; gid = 0; if (options.Detached) { flags |= (uint)uv_process_flags.UV_PROCESS_DETACHED; } if (options.WindowsVerbatimArguments) { flags |= (uint)uv_process_flags.UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; } if (options.UID.HasValue) { flags |= (uint)uv_process_flags.UV_PROCESS_SETUID; uid = options.GID.Value; } if (options.GID.HasValue) { flags |= (uint)uv_process_flags.UV_PROCESS_SETGID; gid = options.GID.Value; } exit_cb = Marshal.GetFunctionPointerForDelegate(cb); stdio_count = (options.Streams == null && !(options.Streams is UVStream[]) ? 0 : options.Streams.Count); if (stdio_count == 0) { stdio = null; return; } stdio = (uv_stdio_container_stream_t *)Marshal.AllocHGlobal(stdio_count * sizeof(uv_stdio_container_stream_t)); int i = 0; foreach (var stream in options.Streams) { stdio[i].flags = 0; if (stream != null) { stdio[i].stream = stream.NativeHandle; if ((stream.readable || stream.writeable) && stream is Pipe) { stdio[i].flags |= uv_stdio_flags.UV_CREATE_PIPE; if (stream.readable) { stdio[i].flags |= uv_stdio_flags.UV_READABLE_PIPE; } if (stream.writeable) { stdio[i].flags |= uv_stdio_flags.UV_WRITABLE_PIPE; } } else if (stream is UVStream) { stdio[i].flags |= uv_stdio_flags.UV_INHERIT_STREAM; } } i++; } }