mirror of
https://github.com/gechandesu/runcmd.git
synced 2026-07-15 00:50:01 +03:00
Compare commits
4
Commits
7390af4699
...
604b9e2d42
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
604b9e2d42 | ||
|
|
ac516c7b6c | ||
|
|
5636f29acd | ||
|
|
6c3f40179b |
@@ -13,9 +13,8 @@ jobs:
|
||||
|
||||
- name: Setup V
|
||||
run: |
|
||||
wget -qO /tmp/v.zip https://github.com/vlang/v/releases/latest/download/v_linux.zip
|
||||
unzip -q /tmp/v.zip -d /tmp
|
||||
echo /tmp/v >> "$GITHUB_PATH"
|
||||
git clone --depth=1 https://github.com/vlang/v /tmp/v && cd /tmp/v && make
|
||||
/tmp/v/v symlink
|
||||
|
||||
- name: Build docs
|
||||
run: |
|
||||
|
||||
@@ -15,9 +15,8 @@ jobs:
|
||||
|
||||
- name: Setup V
|
||||
run: |
|
||||
wget -qO /tmp/v.zip https://github.com/vlang/v/releases/latest/download/v_linux.zip
|
||||
unzip -q /tmp/v.zip -d /tmp
|
||||
echo /tmp/v >> "$GITHUB_PATH"
|
||||
git clone --depth=1 https://github.com/vlang/v /tmp/v && cd /tmp/v && make
|
||||
/tmp/v/v symlink
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
|
||||
@@ -207,7 +207,7 @@ pub fn (mut c Command) start() !int {
|
||||
}
|
||||
|
||||
child_pipes_hook := fn [mut c, pipes] (mut p Process) ! {
|
||||
printdbg('child pipes hook!')
|
||||
printdbg('Command.start: executing child pipes hook...')
|
||||
if !c.redirect_stdio {
|
||||
return
|
||||
}
|
||||
@@ -228,21 +228,21 @@ pub fn (mut c Command) start() !int {
|
||||
if c.redirect_stdio {
|
||||
if c.stdin != none {
|
||||
c.stdio_copy_fns << fn [mut c] () ! {
|
||||
printdbg('Command.start: stdin copy callback called')
|
||||
printdbg('Command.start: stdin copy closure: started')
|
||||
mut fd := c.stdin()!
|
||||
printdbg('Command.start: stdin copy callback: child stdin fd=${fd.fd}')
|
||||
printdbg('Command.start: stdin copy closure: child stdin fd=${fd.fd}')
|
||||
if c.stdin != none {
|
||||
// FIXME: V bug?: without `if` guard acessing
|
||||
// to c.stdin causes SIGSEGV.
|
||||
io_copy(mut c.stdin, mut fd, 'copy stdin')!
|
||||
printdbg('Command.start: stdin copy callback: close child stdin fd after copy')
|
||||
printdbg('Command.start: stdin copy closure: close child stdin fd after copy')
|
||||
fd_close(fd.fd)!
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.stdout != none {
|
||||
c.stdio_copy_fns << fn [mut c] () ! {
|
||||
printdbg('Command.start: stdout copy callback called')
|
||||
printdbg('Command.start: stdout copy closure: started')
|
||||
mut fd := c.stdout()!
|
||||
if c.stdout != none {
|
||||
io_copy(mut fd, mut c.stdout, 'copy stdout')!
|
||||
@@ -251,7 +251,7 @@ pub fn (mut c Command) start() !int {
|
||||
}
|
||||
if c.stderr != none {
|
||||
c.stdio_copy_fns << fn [mut c] () ! {
|
||||
printdbg('Command.start: stderr copy callback called')
|
||||
printdbg('Command.start: stderr copy closure: started')
|
||||
mut fd := c.stderr()!
|
||||
if c.stderr != none {
|
||||
io_copy(mut fd, mut c.stderr, 'copy stderr')!
|
||||
@@ -283,7 +283,9 @@ pub fn (mut c Command) start() !int {
|
||||
for f in c.stdio_copy_fns {
|
||||
go fn (func IOCopyFn) {
|
||||
printdbg('Command.start: starting I/O copy closure in coroutine')
|
||||
func() or { eprintln('error in I/O copy coroutine: ${err}') }
|
||||
func() or {
|
||||
eprintln('error in I/O copy coroutine: msg=${err.msg()}; code=${err.code()}')
|
||||
}
|
||||
}(f)
|
||||
}
|
||||
}
|
||||
@@ -358,7 +360,7 @@ pub fn (c Command) stdin() !WriteFd {
|
||||
WriteFd{c.stdio[0]}
|
||||
} else {
|
||||
printdbg('${@METHOD}: invalid fd -1')
|
||||
error_with_code('Bad file descriptor', 9)
|
||||
error_with_code('File descriptor is not set', 9)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,7 +372,7 @@ pub fn (c Command) stdout() !ReadFd {
|
||||
ReadFd{c.stdio[1]}
|
||||
} else {
|
||||
printdbg('${@METHOD}: invalid fd -1')
|
||||
error_with_code('Bad file descriptor', 9)
|
||||
error_with_code('File descriptor is not set', 9)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +384,7 @@ pub fn (c Command) stderr() !ReadFd {
|
||||
ReadFd{c.stdio[2]}
|
||||
} else {
|
||||
printdbg('${@METHOD}: invalid fd -1')
|
||||
error_with_code('Bad file descriptor', 9)
|
||||
error_with_code('File descriptor is not set', 9)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,11 +414,14 @@ fn io_copy(mut src io.Reader, mut dst io.Writer, msg string) ! {
|
||||
}
|
||||
for {
|
||||
nr := src.read(mut buf) or {
|
||||
printdbg('${@FN}: (${msg}) got error from reader, breaking loop: ${err}')
|
||||
printdbg("${@FN}: (${msg}) got error from reader, breaking loop: msg='${err.msg()}'; code=${err.code()}")
|
||||
break
|
||||
}
|
||||
printdbg('${@FN}: (${msg}) ${nr} bytes read from src to buf')
|
||||
nw := dst.write(buf[..nr]) or { return err }
|
||||
nw := dst.write(buf[..nr]) or {
|
||||
printdbg("${@FN}: (${msg}) got error from writer, exiting: msg='${err.msg()}'; code=${err.code()}")
|
||||
return err
|
||||
}
|
||||
printdbg('${@FN}: (${msg}) ${nw} bytes written to dst')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
module runcmd
|
||||
|
||||
import os
|
||||
|
||||
@[if runcmd_trace ?]
|
||||
fn printdbg(s string) {
|
||||
eprintln('runcmd[pid=${v_getpid()}]: ${s}')
|
||||
text := 'runcmd[pid=${v_getpid()}]: ${s}'
|
||||
eprintln(text)
|
||||
trace_file := $d('runcmd_trace_file', '')
|
||||
if trace_file != '' {
|
||||
file := os.open_append(trace_file) or { return }
|
||||
file.write_string(text + '\n') or {}
|
||||
file.flush()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import runcmd
|
||||
|
||||
fn main() {
|
||||
// Prepare command.
|
||||
mut cmd := runcmd.new('sh', '-c', r'for i in {1..5}; do echo line $i; sleep .5; done; echo finish!')
|
||||
mut cmd := runcmd.new('sh', '-c',
|
||||
r'for i in {1..5}; do echo line $i; sleep .5; done; echo finish!')
|
||||
|
||||
// This is required to captute standart I/O streams.
|
||||
cmd.redirect_stdio = true
|
||||
|
||||
@@ -76,20 +76,20 @@ pub fn (s ProcessState) str() string {
|
||||
sig_str := os.sigint_to_signal_name(sig)
|
||||
str = 'signal: ${sig} (${sig_str})'
|
||||
}
|
||||
// s.status.stopped() {
|
||||
// str = 'stop signal: ${s.status.stop_signal()}'
|
||||
// }
|
||||
// s.status.continued() {
|
||||
// str = 'continued'
|
||||
// }
|
||||
s.status.stopped() {
|
||||
str = 'stop signal: ${s.status.stop_signal()}'
|
||||
}
|
||||
s.status.continued() {
|
||||
str = 'continued'
|
||||
}
|
||||
else {
|
||||
str = 'unknown'
|
||||
}
|
||||
}
|
||||
|
||||
// if s.status.coredump() {
|
||||
// str += ' (core dumped)'
|
||||
// }
|
||||
if s.status.coredump() {
|
||||
str += ' (core dumped)'
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ pub fn (mut p Process) start() !int {
|
||||
os.chdir(p.dir)!
|
||||
}
|
||||
|
||||
printdbg('${@METHOD}: calling execve() with executable `${p.path}`')
|
||||
os.execve(p.path, p.argv, env)!
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
module runcmd
|
||||
|
||||
// fn C.WIFSTOPPED(i32) bool
|
||||
fn C.WIFSTOPPED(int) bool
|
||||
|
||||
// fn C.WCOREDUMP(i32) bool
|
||||
fn C.WCOREDUMP(int) bool
|
||||
|
||||
// fn C.WIFCONTINUED(i32) bool
|
||||
fn C.WIFCONTINUED(int) bool
|
||||
|
||||
// fn C.WSTOPSIG(i32) int
|
||||
fn C.WSTOPSIG(int) int
|
||||
|
||||
// WaitStatus stores the result value of [wait(2)](https://www.man7.org/linux/man-pages/man2/wait.2.html) syscall.
|
||||
pub type WaitStatus = int
|
||||
pub type WaitStatus = u32
|
||||
|
||||
// exited returns true if process is exited.
|
||||
pub fn (w WaitStatus) exited() bool {
|
||||
@@ -37,29 +37,29 @@ pub fn (w WaitStatus) term_signal() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// // stopped returns true if the child process was stopped by delivery of a signal.
|
||||
// pub fn (w WaitStatus) stopped() bool {
|
||||
// return C.WIFSTOPPED(w)
|
||||
// }
|
||||
// stopped returns true if the child process was stopped by delivery of a signal.
|
||||
pub fn (w WaitStatus) stopped() bool {
|
||||
return C.WIFSTOPPED(w)
|
||||
}
|
||||
|
||||
// // stop_signal returns the number of the signal which caused the child to stop.
|
||||
// pub fn (w WaitStatus) stop_signal() int {
|
||||
// if w.stopped() {
|
||||
// return C.WSTOPSIG(w)
|
||||
// }
|
||||
// return -1
|
||||
// }
|
||||
// stop_signal returns the number of the signal which caused the child to stop.
|
||||
pub fn (w WaitStatus) stop_signal() int {
|
||||
if w.stopped() {
|
||||
return C.WSTOPSIG(w)
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// // continued returns true if the child process was resumed by delivery of SIGCONT.
|
||||
// pub fn (w WaitStatus) continued() bool {
|
||||
// return C.WIFCONTINUED(w)
|
||||
// }
|
||||
// continued returns true if the child process was resumed by delivery of SIGCONT.
|
||||
pub fn (w WaitStatus) continued() bool {
|
||||
return C.WIFCONTINUED(w)
|
||||
}
|
||||
|
||||
// // coredump returns true if the child produced a core dump.
|
||||
// // See [core(5)](https://man7.org/linux/man-pages/man5/core.5.html).
|
||||
// pub fn (w WaitStatus) coredump() bool {
|
||||
// if w.signaled() {
|
||||
// return C.WCOREDUMP(w)
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
// coredump returns true if the child produced a core dump.
|
||||
// See [core(5)](https://man7.org/linux/man-pages/man5/core.5.html).
|
||||
pub fn (w WaitStatus) coredump() bool {
|
||||
if w.signaled() {
|
||||
return C.WCOREDUMP(w)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user