v / vlib / os
Raw file | 162 loc (144 sloc) | 3.54 KB | Latest commit hash e419faf74
1module os
2
3fn C.setpgid(pid int, pgid int) int
4
5fn (mut p Process) unix_spawn_process() int {
6 mut pipeset := [6]int{}
7 if p.use_stdio_ctl {
8 mut dont_care := C.pipe(&pipeset[0]) // pipe read end 0 <- 1 pipe write end
9 dont_care = C.pipe(&pipeset[2]) // pipe read end 2 <- 3 pipe write end
10 dont_care = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end
11 _ = dont_care // using `_` directly on each above `pipe` fails to avoid C compiler generate an `-Wunused-result` warning
12 }
13 pid := fork()
14 if pid != 0 {
15 // This is the parent process after the fork.
16 // Note: pid contains the process ID of the child process
17 if p.use_stdio_ctl {
18 p.stdio_fd[0] = pipeset[1] // store the write end of child's in
19 p.stdio_fd[1] = pipeset[2] // store the read end of child's out
20 p.stdio_fd[2] = pipeset[4] // store the read end of child's err
21 // close the rest of the pipe fds, the parent does not need them
22 fd_close(pipeset[0])
23 fd_close(pipeset[3])
24 fd_close(pipeset[5])
25 }
26 return pid
27 }
28 //
29 // Here, we are in the child process.
30 // It still shares file descriptors with the parent process,
31 // but it is otherwise independent and can do stuff *without*
32 // affecting the parent process.
33 //
34 if p.use_pgroup {
35 C.setpgid(0, 0)
36 }
37 if p.use_stdio_ctl {
38 // Redirect the child standart in/out/err to the pipes that
39 // were created in the parent.
40 // Close the parent's pipe fds, the child do not need them:
41 fd_close(pipeset[1])
42 fd_close(pipeset[2])
43 fd_close(pipeset[4])
44 // redirect the pipe fds to the child's in/out/err fds:
45 C.dup2(pipeset[0], 0)
46 C.dup2(pipeset[3], 1)
47 C.dup2(pipeset[5], 2)
48 // close the pipe fdsx after the redirection
49 fd_close(pipeset[0])
50 fd_close(pipeset[3])
51 fd_close(pipeset[5])
52 }
53 if p.work_folder != '' {
54 if !is_abs_path(p.filename) {
55 // Ensure p.filename contains an absolute path, so it
56 // can be located reliably, even after changing the
57 // current folder in the child process:
58 p.filename = abs_path(p.filename)
59 }
60 chdir(p.work_folder) or {}
61 }
62 execve(p.filename, p.args, p.env) or {
63 eprintln(err)
64 exit(1)
65 }
66 return 0
67}
68
69fn (mut p Process) unix_stop_process() {
70 C.kill(p.pid, C.SIGSTOP)
71}
72
73fn (mut p Process) unix_resume_process() {
74 C.kill(p.pid, C.SIGCONT)
75}
76
77fn (mut p Process) unix_kill_process() {
78 C.kill(p.pid, C.SIGKILL)
79}
80
81fn (mut p Process) unix_kill_pgroup() {
82 C.kill(-p.pid, C.SIGKILL)
83}
84
85fn (mut p Process) unix_wait() {
86 cstatus := 0
87 mut ret := -1
88 $if !emscripten ? {
89 ret = C.waitpid(p.pid, &cstatus, 0)
90 }
91 if ret == -1 {
92 p.err = posix_get_error_msg(C.errno)
93 return
94 }
95 pret, is_signaled := posix_wait4_to_exit_status(cstatus)
96 if is_signaled {
97 p.status = .aborted
98 p.err = 'Terminated by signal ${ret:2d} (${sigint_to_signal_name(pret)})'
99 } else {
100 p.status = .exited
101 }
102 p.code = pret
103}
104
105fn (mut p Process) unix_is_alive() bool {
106 cstatus := 0
107 mut ret := -1
108 $if !emscripten ? {
109 ret = C.waitpid(p.pid, &cstatus, C.WNOHANG)
110 }
111 if ret == -1 {
112 p.err = posix_get_error_msg(C.errno)
113 return false
114 }
115 if ret == 0 {
116 return true
117 }
118 pret, is_signaled := posix_wait4_to_exit_status(cstatus)
119 if is_signaled {
120 p.status = .aborted
121 p.err = 'Terminated by signal ${ret:2d} (${sigint_to_signal_name(pret)})'
122 } else {
123 p.status = .exited
124 }
125 p.code = pret
126 return false
127}
128
129// these are here to make v_win.c/v.c generation work in all cases:
130fn (mut p Process) win_spawn_process() int {
131 return 0
132}
133
134fn (mut p Process) win_stop_process() {
135}
136
137fn (mut p Process) win_resume_process() {
138}
139
140fn (mut p Process) win_kill_process() {
141}
142
143fn (mut p Process) win_kill_pgroup() {
144}
145
146fn (mut p Process) win_wait() {
147}
148
149fn (mut p Process) win_is_alive() bool {
150 return false
151}
152
153fn (mut p Process) win_write_string(idx int, s string) {
154}
155
156fn (mut p Process) win_read_string(idx int, maxbytes int) (string, int) {
157 return '', 0
158}
159
160fn (mut p Process) win_slurp(idx int) string {
161 return ''
162}