Skip to content

Instantly share code, notes, and snippets.

@lispmeister
Last active April 6, 2017 07:47
Show Gist options
  • Save lispmeister/db25536d892d01fe35f28d73fe1eb662 to your computer and use it in GitHub Desktop.
Save lispmeister/db25536d892d01fe35f28d73fe1eb662 to your computer and use it in GitHub Desktop.
STDIN processing bug in process package #945
use "process"
use "files"
use "options"
actor Main
let _env: Env
new create(env: Env) =>
_env = env
var lines: (I64 | None) = None
var required_args_are_present: Bool = true
// parse commandline
try
var options = Options(env)
options
.add("lines", "l", I64Argument)
for option in options do
match option
| ("lines", let arg: I64) => lines = arg
else
env.err.print("stdin-process-test: unknown argument")
env.err.print("stdin-process-test: usage: [--lines=2000]")
end
end
// check lines value
if lines is None then
env.err.print("dagon: Must supply required '--lines' argument")
required_args_are_present = false
elseif (lines as I64) < 0 then
env.err.print("stdin-process-test: lines can't be negative")
required_args_are_present = false
end
if not required_args_are_present then
env.err.print("stdin-process-test: error parsing arguments. Bailing out!")
return
end
// create a notifier
let client = ProcessClient(_env)
let notifier: ProcessNotify iso = consume client
// define the binary to run
try
let path = FilePath(env.root as AmbientAuth, "/usr/bin/wc")
// define the arguments; first arg is always the binary name
let args: Array[String] iso = recover Array[String](2) end
args.push("wc")
args.push("-l")
// define the environment variable for the execution
let vars: Array[String] iso = recover Array[String](2) end
vars.push("HOME=/")
vars.push("PATH=/bin")
// create a ProcessMonitor and spawn the child process
let pm: ProcessMonitor = ProcessMonitor(consume notifier, path,
consume args, consume vars)
// write to STDIN of the child process
var i:I64 = 0
while i < (lines as I64) do
pm.write("..............................\n")
i = i + 1
end
pm.done_writing() // closing stdin
else
env.err.print("stdin-process-test: Could not create FilePath!")
end
else
env.err.print("stdin-process-test: error parsing arguments")
end
// define a client that implements the ProcessNotify interface
class ProcessClient is ProcessNotify
let _env: Env
new iso create(env: Env) =>
_env = env
fun ref stdout(data: Array[U8] iso) =>
let out = String.from_array(consume data)
_env.out.print("STDOUT: " + out)
fun ref stderr(data: Array[U8] iso) =>
let err = String.from_array(consume data)
_env.out.print("STDERR: " + err)
fun ref failed(err: ProcessError) =>
match err
| ExecveError => _env.out.print("ProcessError: ExecveError")
| PipeError => _env.out.print("ProcessError: PipeError")
| Dup2Error => _env.out.print("ProcessError: Dup2Error")
| ForkError => _env.out.print("ProcessError: ForkError")
| FcntlError => _env.out.print("ProcessError: FcntlError")
| WaitpidError => _env.out.print("ProcessError: WaitpidError")
| CloseError => _env.out.print("ProcessError: CloseError")
| ReadError => _env.out.print("ProcessError: ReadError")
| WriteError => _env.out.print("ProcessError: WriteError")
| KillError => _env.out.print("ProcessError: KillError")
| Unsupported => _env.out.print("ProcessError: Unsupported")
else
_env.out.print("Unknown ProcessError!")
end
fun ref dispose(child_exit_code: I32) =>
let code: I32 = consume child_exit_code
_env.out.print("Child exit code: " + code.string())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment