Create this script called "foo.pl": --cut here-- #!/usr/bin/perl if (! ($pid = fork)) { close(STDIN); close(STDOUT); close(STDERR); sleep(5); exit(0); } else { exit(0); } --cut here-- Now create this tcl script, called "foo.tcl": --cut here-- exec foo.pl exit --cut here-- Now run "tclsh foo.tcl". It will exit after five seconds. It *should* exit immediately, and indeed, it does exit immediately in tcl-8.0.5-34. I've managed to figure out that the child process started by tcl's "exec" call is inheriting some file descriptors which should have been set to close on exec by tcl but weren't. When "exit" is called in the tcl script, tcl waits until those file descriptors are closed before it actually exits. This is obnoxious, undocumented, just plain wrong behavior. You can confirm this by creating this file foo.c: --cut here-- #include <stdio.h> main() { int i; if (fork()) { exit(0); } for (i = 0; i < 64; i++) { close(i); } sleep(5); exit(0); } --cut here-- Compile this with "gcc -o foo foo.c", then change foo.tcl so that it calls "exec ./foo" instead of "exec ./foo.pl", then run "tcl foo.tcl" and it'll exit immediately. If you take out the "close(i);" and recompile foo.c to foo, foo.tcl will once again take five seconds to exit. This is a serious problem which makes it virtually impossible to construct tcl or expect scripts which launch daemons or do other common things which intentionally leave processes sitting around after the script exits.
What version of tcltk?
tcltk-8.2.3-36 doesn't work. tcltk-8.0.5-34 works. Sorry I forgot to mention this.
This is fixed in tcl 8.3.1.
Fixed (by upgrading to tcl-8.3.1) in Raw Hide. Thanks for reporting the problem (and fix).