aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/os/process.js.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/os/process.js.v')
-rw-r--r--v_windows/v/vlib/os/process.js.v117
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()')
+ }
+}