Posted to tcl by evilotto at Wed Jun 26 17:57:48 GMT 2013view pretty
~ Abstract This proposal is to add a cleaner interface to spawning subprocesses ~ Rationale Tcl has long had the ''exec'' command which works for many purposes but has several areas of inflexibility that make certain edge cases very difficult to handle, especially its handling of shell metacharacters internally. A replacement command that provides simpler and more orthogonal functionality would enable pipeline building in tcl code. ~ Requirements Any replacement for creating subprocesses should support: 1. spawning a subprocess with a given argument list 2. spwaning a subprocess with a different executable than command line argument 3. assigning a set of open tcl channels to fds of a spawned subprocess 4. passing a specific environment to the spawned subprocess 5. capturing the exit status of a spawned subprocess. ~ Specification Handling of subprocesses will be done through a ''process'' ensemble. 1. ''process create ?-executable path? ?-env dict? ?-fds dict? arg0 ?argn ...?'' Creates (fork/execs) the new subprocess and returns a handle to it. If the '-executable'' flag is specified, its argument is used as the executable filename (i.e., the filename argument to execve); if this flag is not specified then ''arg0'' is used. If the '-env' flag is specified, the dict given is used to create the environment for the subprocess. If it is not specified, the current environment ( ::env ) is used. If the '-fds' flag is specified, the dict is expected to have integer keys and names of open channels with the correct modes as values. These are passed to the child process. Any fd not specified in the dict will be closed. If this argument is not present, the default value {0 stdin 1 stdout 2 stderr} is used. The arguments are passed to the subprocess without further interpretation. 2. ''process wait handle'' Waits for the subprocess specified by 'handle' to exit, and returns the exit status of that process. ~ Examples Current example: set out [exec cat /tmp/afile] Process example: set so_pipe [chan pipe] set se_pipe [chan pipe] set fds [list 0 {} 1 [lindex $so_pipe 1] 2 [lindex $se_pipe 1]] set handle [process create -fds $fds cat /tmp/afile] set out [read [lindex $so_pipe 0]] process wait $handle Current example: exec mail sample@example.com << $text Process example set si_pipe [chan pipe] set so_pipe [chan pipe] set se_pipe [chan pipe] set fds [list 0 [lindex $si_pipe 0] 1 [lindex $so_pipe 1] 2 [lindex $se_pipe 1]] set handle [process create -fds $fds mail sample@example.com] puts [lindex $si_pipe 1] $text close [lindex $si_pipe 1] process wait $handle While there is considerably more setup needed for the ''process'' usage than for ''exec'', it is assumed that this will generally be hidden inside a wrapper proc. ~ Copyright This document has been placed in the public domain.