Both TclX and Expect implement the Unix-familiar fork/exec/wait interfaces, more-or-less. How can core Tcl get along without them? Its exec and open interfaces are slightly higher-level abstractions that make more sense across platforms, and have proven to be quite apt for development. Note, in particular, that [... exec reaps from ...].
The TclX package provides the command with this syntax:
Waits for a process (created with fork, exec or open) to terminate, whether by signal or by a call to exit. If pid is given, wait for that specific process, and otherwise wait for any child process. This will also pick up exit codes from already-terminated processes (“zombies”). Note that exec and open will automatically reap the zombies they create with repeated use; there is no guarantee that you will be able to manually wait for the processes they create.
The result of wait is a list of three elements (per reaped process):
Pid is the exit code. If the process exited normally, type is EXIT and code is the exit code. If the process terminated due to a signal, type is SIG and code is the signal name. If the process is stopped, type is STOP and code is the signal that caused it to suspend.