diff options
Diffstat (limited to 'v_windows/v/vlib/os/process.js.v')
-rw-r--r-- | v_windows/v/vlib/os/process.js.v | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/v_windows/v/vlib/os/process.js.v b/v_windows/v/vlib/os/process.js.v new file mode 100644 index 0000000..dc15c8b --- /dev/null +++ b/v_windows/v/vlib/os/process.js.v @@ -0,0 +1,117 @@ +module os + +#const $child_process = require('child_process') + +// new_process - create a new process descriptor +// NB: new does NOT start the new process. +// That is done because you may want to customize it first, +// by calling different set_ methods on it. +// In order to start it, call p.run() or p.wait() +pub fn new_process(filename string) &Process { + return &Process{ + filename: filename + stdio_fd: [-1, -1, -1]! + } +} + +fn (mut p Process) spawn_internal() { + #p.val.pid = $child_process.spawn( + #p.val.filename+'', + #p.val.args.arr.map((x) => x.valueOf() + ''), + #{ + #env: (p.val.env_is_custom ? p.val.env : $process.env), + #}) + #p.val.pid.on('error', function (err) { builtin.panic('Failed to start subprocess') }) + + p.status = .running + // todo(playX): stderr,stdin + if p.use_stdio_ctl { + #p.val.pid.stdout.pipe(process.stdout) + #p.val.pid.stdin.pipe(process.stdin) + #p.val.pid.stderr.pipe(process.stderr) + } +} + +pub fn (mut p Process) run() { + if p.status != .not_started { + return + } + p.spawn_internal() + return +} + +pub fn (mut p Process) signal_kill() { + if p.status !in [.running, .stopped] { + return + } + #p.val.pid.kill('SIGKILL'); + + p.status = .aborted +} + +pub fn (mut p Process) signal_stop() { + if p.status !in [.running, .stopped] { + return + } + #p.val.pid.kill('SIGSTOP'); + + p.status = .aborted +} + +pub fn (mut p Process) signal_continue() { + if p.status != .stopped { + return + } + #p.val.pid.kill('SIGCONT'); + + p.status = .running + return +} + +pub fn (mut p Process) wait() { + if p.status == .not_started { + p.spawn_internal() + } + if p.status !in [.running, .stopped] { + return + } + + p.wait_internal() + return +} + +fn (mut p Process) wait_internal() { + #p.val.pid.on('exit', function (code) { console.log(code) }) +} + +pub fn (mut p Process) set_redirect_stdio() { + p.use_stdio_ctl = true + return +} + +pub fn (mut p Process) stdin_write(s string) { + p.check_redirection_call('stdin_write') + #p.val.pid.stdin.write(s) +} + +// todo(playX): probably does not work + +// will read from stdout pipe, will only return when EOF (end of file) or data +// means this will block unless there is data +pub fn (mut p Process) stdout_slurp() string { + p.check_redirection_call('stdout_slurp') + mut res := '' + #p.val.pid.stdout.on('data', function (data) { res = new builtin.string(data) }) + + return res +} + +// _check_redirection_call - should be called just by stdxxx methods +fn (mut p Process) check_redirection_call(fn_name string) { + if !p.use_stdio_ctl { + panic('Call p.set_redirect_stdio() before calling p.$fn_name') + } + if p.status == .not_started { + panic('Call p.${fn_name}() after you have called p.run()') + } +} |