From f5c4671bfbad96bf346bd7e9a21fc4317b4959df Mon Sep 17 00:00:00 2001 From: Indrajith K L Date: Sat, 3 Dec 2022 17:00:20 +0530 Subject: Adds most of the tools --- v_windows/v/examples/process/.ignore | 1 + v_windows/v/examples/process/command.v | 34 +++++++++ v_windows/v/examples/process/execve.v | 17 +++++ v_windows/v/examples/process/process_script.v | 59 +++++++++++++++ v_windows/v/examples/process/process_stdin_trick.v | 83 ++++++++++++++++++++++ 5 files changed, 194 insertions(+) create mode 100644 v_windows/v/examples/process/.ignore create mode 100644 v_windows/v/examples/process/command.v create mode 100644 v_windows/v/examples/process/execve.v create mode 100644 v_windows/v/examples/process/process_script.v create mode 100644 v_windows/v/examples/process/process_stdin_trick.v (limited to 'v_windows/v/examples/process') diff --git a/v_windows/v/examples/process/.ignore b/v_windows/v/examples/process/.ignore new file mode 100644 index 0000000..e42252a --- /dev/null +++ b/v_windows/v/examples/process/.ignore @@ -0,0 +1 @@ +command \ No newline at end of file diff --git a/v_windows/v/examples/process/command.v b/v_windows/v/examples/process/command.v new file mode 100644 index 0000000..718ce96 --- /dev/null +++ b/v_windows/v/examples/process/command.v @@ -0,0 +1,34 @@ +module main + +import os + +// basic example which shows how to use the Command function + +fn exec(path string) string { + mut out := '' + mut line := '' + mut cmd := os.Command{ + path: path + } + cmd.start() or { panic(err) } + + for { + line = cmd.read_line() + println(line) + out += line + if cmd.eof { + return out + } + } + return out +} + +fn main() { + mut out := '' + exec("bash -c 'find /tmp/'") + out = exec('echo to stdout') + out = exec('echo to stderr 1>&2') + println("'$out'") + // THIS DOES NOT WORK, is error, it goes to stderror of the command I run + assert out == 'to stderr' +} diff --git a/v_windows/v/examples/process/execve.v b/v_windows/v/examples/process/execve.v new file mode 100644 index 0000000..f840c8d --- /dev/null +++ b/v_windows/v/examples/process/execve.v @@ -0,0 +1,17 @@ +module main + +import os + +fn exec(args []string) { + os.execve('/bin/bash', args, []) or { + // eprintln(err) + panic(err) + } +} + +fn main() { + // exec(["-c","find /"]) //works + exec(['-c', 'find /tmp/']) // here it works as well + + // exec(["-c","find","/tmp/"]) // does not work I guess is normal +} diff --git a/v_windows/v/examples/process/process_script.v b/v_windows/v/examples/process/process_script.v new file mode 100644 index 0000000..fa415e7 --- /dev/null +++ b/v_windows/v/examples/process/process_script.v @@ -0,0 +1,59 @@ +module main + +import os + +// a test where we execute a bash script but work around where we put script in bash inside bash + +fn exec(path string, redirect bool) { + mut line := '' + mut line_err := '' + mut cmd := os.new_process('/bin/bash') + + if redirect { + cmd.set_args(['-c', '/bin/bash /tmp/test.sh 2>&1']) + } else { + cmd.set_args([path]) + } + + cmd.set_redirect_stdio() + cmd.run() + if cmd.is_alive() { + for { + line = cmd.stdout_read() + println('STDOUT: $line') + + if !redirect { + line_err = cmd.stderr_read() + println('STDERR: $line_err') + } + + if !cmd.is_alive() { + break + } + } + } + if cmd.code > 0 { + println('ERROR:') + println(cmd) + // println(cmd.stderr_read()) + } +} + +fn main() { + script := ' +echo line 1 +#will use some stderr now +echo redirect 1 to 2 1>&2 +echo line 3 +' + + os.write_file('/tmp/test.sh', script) or { panic(err) } + // os.chmod("/tmp/test.sh",0o700) //make executable + + // this will work because stderr/stdout are smaller than 4096 chars, once larger there can be deadlocks + // in other words this can never work reliably without being able to check if there is data on stderr or stdout + exec('/tmp/test.sh', false) + + // this will always work + exec('/tmp/test.sh', true) +} diff --git a/v_windows/v/examples/process/process_stdin_trick.v b/v_windows/v/examples/process/process_stdin_trick.v new file mode 100644 index 0000000..7a1455d --- /dev/null +++ b/v_windows/v/examples/process/process_stdin_trick.v @@ -0,0 +1,83 @@ +module main + +import os + +// this is a example script to show you stdin can be used and keep a process open + +fn exec(cmd string) (string, int) { + mut cmd2 := cmd + mut out := '' + mut line := '' + mut rc := 0 + mut p := os.new_process('/bin/bash') + + // there are methods missing to know if stderr/stdout has data as such its better to redirect bot on same FD + // not so nice trick to run bash in bash and redirect stderr, maybe someone has a better solution + p.set_args(['-c', 'bash 2>&1']) + p.set_redirect_stdio() + p.run() + + if !cmd2.ends_with('\n') { + cmd2 += '\n' + } + + p.stdin_write(cmd2) + p.stdin_write('\necho **OK**\n') + + for { + if !p.is_alive() { + break + } + line = p.stdout_read() + println(line) + // line_err = p.stderr_read() //IF WE CALL STDERR_READ will block + // we need a mechanism which allows us to check if stderr/stdout has data or it should never block + // is not a good way, need to use a string buffer, is slow like this + out += line + if out.ends_with('**OK**\n') { + out = out[0..(out.len - 7)] + break + } + } + + // println("read from stdout, should not block") + // is not really needed but good test to see behaviour + // out += p.stdout_read() + // println("read done") + + // println(cmd.stderr_read()) + + if p.code > 0 { + rc = 1 + println('ERROR:') + println(cmd2) + print(out) + } + // documentation says we need to call p.wait(), but this does not seem to work, will be process stop or become zombie? + // p.wait() + + return out, rc +} + +fn main() { + mut out := '' + mut rc := 0 + + // the following does not work, not sure why not + // out,rc = exec("find /tmp/ && echo '******'") + + out, rc = exec("find /tmp/ ; echo '******'") + println(out) + assert out.ends_with('******\n') + + out, rc = exec('echo to stdout') + assert out.contains('to stdout') + + out, rc = exec('echo to stderr 1>&2') + assert out.contains('to stderr') + + out, rc = exec('ls /sssss') + assert rc > 0 // THIS STILL GIVES AN ERROR ! + + println('test ok stderr & stdout is indeed redirected') +} -- cgit v1.2.3