diff options
Diffstat (limited to 'v_windows/v/vlib/os/process_nix.c.v')
-rw-r--r-- | v_windows/v/vlib/os/process_nix.c.v | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/v_windows/v/vlib/os/process_nix.c.v b/v_windows/v/vlib/os/process_nix.c.v new file mode 100644 index 0000000..74140d1 --- /dev/null +++ b/v_windows/v/vlib/os/process_nix.c.v @@ -0,0 +1,146 @@ +module os + +fn C.setpgid(pid int, pgid int) int + +fn (mut p Process) unix_spawn_process() int { + mut pipeset := [6]int{} + if p.use_stdio_ctl { + _ = C.pipe(&pipeset[0]) // pipe read end 0 <- 1 pipe write end + _ = C.pipe(&pipeset[2]) // pipe read end 2 <- 3 pipe write end + _ = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end + } + pid := fork() + if pid != 0 { + // This is the parent process after the fork. + // NB: pid contains the process ID of the child process + if p.use_stdio_ctl { + p.stdio_fd[0] = pipeset[1] // store the write end of child's in + p.stdio_fd[1] = pipeset[2] // store the read end of child's out + p.stdio_fd[2] = pipeset[4] // store the read end of child's err + // close the rest of the pipe fds, the parent does not need them + fd_close(pipeset[0]) + fd_close(pipeset[3]) + fd_close(pipeset[5]) + } + return pid + } + // + // Here, we are in the child process. + // It still shares file descriptors with the parent process, + // but it is otherwise independant and can do stuff *without* + // affecting the parent process. + // + if p.use_pgroup { + C.setpgid(0, 0) + } + if p.use_stdio_ctl { + // Redirect the child standart in/out/err to the pipes that + // were created in the parent. + // Close the parent's pipe fds, the child do not need them: + fd_close(pipeset[1]) + fd_close(pipeset[2]) + fd_close(pipeset[4]) + // redirect the pipe fds to the child's in/out/err fds: + C.dup2(pipeset[0], 0) + C.dup2(pipeset[3], 1) + C.dup2(pipeset[5], 2) + // close the pipe fdsx after the redirection + fd_close(pipeset[0]) + fd_close(pipeset[3]) + fd_close(pipeset[5]) + } + execve(p.filename, p.args, p.env) or { + eprintln(err) + exit(1) + } + return 0 +} + +fn (mut p Process) unix_stop_process() { + C.kill(p.pid, C.SIGSTOP) +} + +fn (mut p Process) unix_resume_process() { + C.kill(p.pid, C.SIGCONT) +} + +fn (mut p Process) unix_kill_process() { + C.kill(p.pid, C.SIGKILL) +} + +fn (mut p Process) unix_kill_pgroup() { + C.kill(-p.pid, C.SIGKILL) +} + +fn (mut p Process) unix_wait() { + cstatus := 0 + ret := C.waitpid(p.pid, &cstatus, 0) + if ret == -1 { + p.err = posix_get_error_msg(C.errno) + return + } + pret, is_signaled := posix_wait4_to_exit_status(cstatus) + if is_signaled { + p.status = .aborted + p.err = 'Terminated by signal ${ret:2d} (${sigint_to_signal_name(pret)})' + } else { + p.status = .exited + } + p.code = pret +} + +fn (mut p Process) unix_is_alive() bool { + cstatus := 0 + ret := C.waitpid(p.pid, &cstatus, C.WNOHANG) + if ret == -1 { + p.err = posix_get_error_msg(C.errno) + return false + } + if ret == 0 { + return true + } + pret, is_signaled := posix_wait4_to_exit_status(cstatus) + if is_signaled { + p.status = .aborted + p.err = 'Terminated by signal ${ret:2d} (${sigint_to_signal_name(pret)})' + } else { + p.status = .exited + } + p.code = pret + return false +} + +// these are here to make v_win.c/v.c generation work in all cases: +fn (mut p Process) win_spawn_process() int { + return 0 +} + +fn (mut p Process) win_stop_process() { +} + +fn (mut p Process) win_resume_process() { +} + +fn (mut p Process) win_kill_process() { +} + +fn (mut p Process) win_kill_pgroup() { +} + +fn (mut p Process) win_wait() { +} + +fn (mut p Process) win_is_alive() bool { + return false +} + +fn (mut p Process) win_write_string(idx int, s string) { +} + +fn (mut p Process) win_read_string(idx int, maxbytes int) (string, int) { + return '', 0 +} + +fn (mut p Process) win_slurp(idx int) string { + return '' +} |