Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,80 @@
|
||||
module os
|
||||
|
||||
import strings
|
||||
|
||||
// Command represents a running shell command, that the parent process
|
||||
// wishes to monitor for output on its stdout pipe.
|
||||
pub struct Command {
|
||||
mut:
|
||||
f voidptr
|
||||
pub mut:
|
||||
eof bool
|
||||
exit_code int
|
||||
pub:
|
||||
path string
|
||||
redirect_stdout bool
|
||||
}
|
||||
|
||||
// start_new_command will create a new os.Command, and start it right away.
|
||||
// The command will represent a process running the passed shell command `cmd`,
|
||||
// in a way that you can later call c.read_line() to intercept the new child process
|
||||
// output line by line, streaming while the command is running.
|
||||
// See also c.eof, c.read_line(), c.close() and c.exit_code .
|
||||
pub fn start_new_command(cmd string) !Command {
|
||||
mut res := Command{
|
||||
path: cmd
|
||||
}
|
||||
res.start()!
|
||||
return res
|
||||
}
|
||||
|
||||
// start will start the command. Use start_new_command/1 instead.
|
||||
@[manualfree]
|
||||
pub fn (mut c Command) start() ! {
|
||||
pcmd := c.path + ' 2>&1'
|
||||
defer {
|
||||
unsafe { pcmd.free() }
|
||||
}
|
||||
c.f = vpopen(pcmd)
|
||||
if isnil(c.f) {
|
||||
return error('exec("${c.path}") failed')
|
||||
}
|
||||
}
|
||||
|
||||
// read_line returns a single line from the stdout of the running command.
|
||||
// Note: c.eof will be set to true, if the command ended while a line was read.
|
||||
// The returned line will contain all of the accumulated output before the process ended.
|
||||
// In practice, that often means, you will get a single '' and c.eof == true at the end.
|
||||
@[manualfree]
|
||||
pub fn (mut c Command) read_line() string {
|
||||
buf := [4096]u8{}
|
||||
mut res := strings.new_builder(1024)
|
||||
defer { unsafe { res.free() } }
|
||||
unsafe {
|
||||
bufbp := &u8(&buf[0])
|
||||
for C.fgets(&char(bufbp), 4096, c.f) != 0 {
|
||||
len := vstrlen(bufbp)
|
||||
for i in 0 .. len {
|
||||
if bufbp[i] == `\n` {
|
||||
res.write_ptr(bufbp, i)
|
||||
final := res.str()
|
||||
return final
|
||||
}
|
||||
}
|
||||
res.write_ptr(bufbp, len)
|
||||
}
|
||||
}
|
||||
c.eof = true
|
||||
final := res.str()
|
||||
return final
|
||||
}
|
||||
|
||||
// close will close the pipe to the command, and wait for the command to finish,
|
||||
// then set .exit_code according to how its final process status.
|
||||
pub fn (mut c Command) close() ! {
|
||||
c.exit_code = vpclose(c.f)
|
||||
c.f = unsafe { nil }
|
||||
if c.exit_code == 127 {
|
||||
return error_with_code('error', 127)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user