v / vlib / os
Raw file | 126 loc (104 sloc) | 2.67 KB | Latest commit hash 017ace6ea
1module os
2
3$if js_node {
4 #const $child_process = require('child_process')
5}
6
7// new_process - create a new process descriptor
8// Note: new does NOT start the new process.
9// That is done because you may want to customize it first,
10// by calling different set_ methods on it.
11// In order to start it, call p.run() or p.wait()
12pub fn new_process(filename string) &Process {
13 return &Process{
14 filename: filename
15 stdio_fd: [-1, -1, -1]!
16 }
17}
18
19fn (mut p Process) spawn_internal() {
20 #p.val.pid = $child_process.spawn(
21 #p.val.filename+'',
22 #p.val.args.arr.map((x) => x.valueOf() + ''),
23 #{
24 #env: (p.val.env_is_custom ? p.val.env : $process.env),
25 #})
26 #p.val.pid.on('error', function (err) { builtin.panic('Failed to start subprocess') })
27
28 p.status = .running
29 if p.use_stdio_ctl {
30 #p.val.pid.stdout.pipe(process.stdout)
31 #p.val.pid.stdin.pipe(process.stdin)
32 #p.val.pid.stderr.pipe(process.stderr)
33 }
34}
35
36pub fn (mut p Process) run() {
37 if p.status != .not_started {
38 return
39 }
40 p.spawn_internal()
41 return
42}
43
44pub fn (mut p Process) signal_kill() {
45 if p.status !in [.running, .stopped] {
46 return
47 }
48 #p.val.pid.kill('SIGKILL');
49
50 p.status = .aborted
51}
52
53pub fn (mut p Process) signal_stop() {
54 if p.status !in [.running, .stopped] {
55 return
56 }
57 #p.val.pid.kill('SIGSTOP');
58
59 p.status = .aborted
60}
61
62pub fn (mut p Process) signal_continue() {
63 if p.status != .stopped {
64 return
65 }
66 #p.val.pid.kill('SIGCONT');
67
68 p.status = .running
69 return
70}
71
72pub fn (mut p Process) wait() {
73 if p.status == .not_started {
74 p.spawn_internal()
75 }
76 if p.status !in [.running, .stopped] {
77 return
78 }
79
80 p.wait_internal()
81 return
82}
83
84fn (mut p Process) wait_internal() {
85 #p.val.pid.on('exit', function (code) { console.log(code) })
86}
87
88pub fn (mut p Process) set_redirect_stdio() {
89 p.use_stdio_ctl = true
90 return
91}
92
93pub fn (mut p Process) stdin_write(s string) {
94 p.check_redirection_call('stdin_write')
95 #p.val.pid.stdin.write(s)
96}
97
98pub fn (mut p Process) stdin_resume() {
99 #p.val.pid.stdin.resume()
100}
101
102// todo(playX): probably does not work
103
104// will read from stdout pipe, will only return when EOF (end of file) or data
105// means this will block unless there is data
106pub fn (mut p Process) stdout_slurp() string {
107 p.check_redirection_call('stdout_slurp')
108 mut res := ''
109 #p.val.pid.stdout.on('data', function (data) { res = new string(data) })
110
111 return res
112}
113
114// _check_redirection_call - should be called just by stdxxx methods
115fn (mut p Process) check_redirection_call(fn_name string) {
116 if !p.use_stdio_ctl {
117 panic('Call p.set_redirect_stdio() before calling p.${fn_name}')
118 }
119 if p.status == .not_started {
120 panic('Call p.${fn_name}() after you have called p.run()')
121 }
122}
123
124pub fn (mut p Process) close() {
125 // no-op on JS backend
126}