[Expect] Is the "catch" in the "catch wait result" idiom really necessary? It seems very broken.
I see this a lot in example code, where people wait on a process to exit and then collect it's return code using "catch wait result" and then usually do something like "exit [lindex $result 3]" to return the process' exit code. This doesn't seem right at all.
Firstoff, it seems like wait already does a pretty good job of handling weird process termination. From [1]:
> wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. The global variable errorCode is also set.
so it seems like "set result [wait]" would be sufficient. Or even "exit [lindex [wait] 3]" (see postscript for caveats).
Second, nobody actually seems to be checking the returncode of catch, they're just silently catching any errors and continuing. Going by [2] this means that if wait did fail, then result will not contain the 4-element list people are anticipating:
> When the return code from the script is 1 (TCL_ERROR), the value stored in varName is an error message. When the return code from the script is 0 (TCL_OK), the value stored in resultVarName is the value returned from script.
Meaning in the case that catch does do something and somehow catches an error from wait, the variable $result will contain some random string of text which may or may not be an iterable list. (could be something like "killed" or "no space left on device"?) It's very possible that "exit [lindex $result 3]" would result in trying to return the 4th word of a textual error message as a returncode, which probably isn't likely to go very well.
If anyone knows of a case where wait could fail with TCL_ERROR etc, please do chime in.
[1] https://www.tcl-lang.org/man/expect5.31/expect.1.html
[2] https://www.tcl-lang.org/man/tcl8.4/TclCmd/catch.htm
P.S. technically "exit [lindex [wait] 3]" still only sort-of correct, since if "lindex [wait] 2" is -1 you're returning the OS errno not the process returncode. Most (but not all) of the time they agree that 0 is success (so if you're using this as a wrapper you'll probably still detect the presence of an error correctly) but actually trying to interpret the error condition outside of expect is likely to go haywire when the OS-generated errno is misinterpreted as a return code from the process itself.
An actual situation where a process exits with non-zero as success (eg. 1) is a very tricky one indeed, because then any failure in TCL could be misinterpreted. This gets tricky because your TCL script either has to be infallible(?) or surrounded in catch, with logic to return some made-up returncode. You'd think this to be a rare occurrence, but I've seen software in the wild that does things like return 0/1/2/3 to indicate one of four successful outcomes, or returns the number of items processed.