TIP #462: Add New [info ps] Ensemble for Subprocess Management

Title:Add New [info ps] Ensemble for Subprocess Management
Version:$Revision: 1.4 $
Author:Frédéric Bonnet <fredericbonnet at free dot fr>
Created:Monday, 23 January 2017


This TIP proposes to improve Tcl's handling of subprocesses created by the exec and open commands by adding a new ::tcl::process ensemble.


This TIP is inspired by a https://github.com/flightaware/Tcl-bounties#stop-tcl-from-eating-child-process-exit-status-gratuitously%|%request from FlightAware%|% to fix the way Tcl currently handles child process exit status.

Subprocess creation can be either synchronous or asynchronous. In either case, a children with a non-zero return value indicates an error condition that is bubbled up to the Tcl error handling mechanism.

Synchronous subprocesses

Synchronous subprocesses are created using the exec command with no & terminal argument. Errors are raised synchronously as well.

Asynchronous subprocesses

Asynchronous subprocesses can be created using two distinct methods:

Error handling and status code

Errors are caught with the catch and try commands, with status codes given in the -errorcode options dictionary entry and the errorCode global variable in the form {CHILDKILLED pid sigName msg} / {CHILDSTATUS pid code} / {CHILDSUSP pid sigName msg}.

C-level access

The Tcl library provides the following procedures for managing subprocesses (excerpts from the Tcl documentation):

Moreover, Tcl_WaitPid is blocking unless called with the WNOHANG option.


The current implementation is lacking several key features:


A new ::tcl::process will be created:

::tcl::process subcommand ?arg ...: Subprocess management.

The following subcommand values are supported by ::tcl::process:

Additionally, ::tcl::process status accepts the following switches:

* '''-wait'''

By default the command returns immediately (the underlying Tcl_WaitPid is called with the WNOHANG flag set) unless this switch is set. If pids is specified as a list of PIDs then the command waits until the matching subprocess statuses are available. If pids is not specified then it waits for all known subprocesses.

* '''--'''

Marks the end of switches. The argument following this one will be treated as the first arg even if it starts with a -.


% ::tcl::process autopurge
% ::tcl::process autopurge false

% set pid1 [exec command1 a b c | command2 d e f &]
123 456
% set chan [open "|command1 a b c | command2 d e f"]
% set pid2 [pid $chan]
789 1011

% ::tcl::process list
123 456 789 1011

% ::tcl::process status
123 {CHILDSTATUS 123 0} 456 {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"} 789 {CHILDSUSP 789 SIGTTIN "background tty read"} 1011 {}

% ::tcl::process status 123
123 {CHILDSTATUS 123 0}

% ::tcl::process status 1011
1011 {}

% ::tcl::process status -wait
123 {CHILDSTATUS 123 0} 456 {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"} 789 {CHILDSUSP 789 SIGTTIN "background tty read"} 1011 {CHILDSTATUS 1011 -1}

% ::tcl::process status 1011
1011 {CHILDSTATUS 1011 -1}

% ::tcl::process purge
% exec command1 1 2 3 &
% ::tcl::process list

Rejected Alternatives

The first version proposed to implement the feature as a new ps option to the existing info command. However, almost all operations in [info] are things that just examine state, not change it, and that's a principle-of-least-astonishment that should be upheld for the sake of less experienced users.

Reference implementation



This document has been placed in the public domain.

Powered by Tcl[Index] [History] [Edit] [HTML Format] [Source Format] [LaTeX Format] [Text Format] [XML Format] [*roff Format (experimental)] [RTF Format (experimental)]

TIP AutoGenerator - written by Donal K. Fellows