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.