Wandering Thoughts archives

2023-12-03

A bit more trivia on the Unix V6 shell and its control flow

Over on the Fediverse, I posted about how the V6 'goto' and 'exit' worked, and got a good question in response, namely how did 'goto' and 'exit' get hold of the file descriptor for the script that the V6 shell was executing. The answer turns out to be that the V6 shell always read from standard input (fd 0). If it was running a script, it arranged to open the script with file descriptor 0 (standard input), which it passed on to all children as usual.

(In my Fediverse answer I said it used 'dup()', but the V6 sh.c says I'm wrong. V6 sh.c simply closed fd 0 just before it open()'d the script, insuring that the open() would give it fd 0. There was also special code to 'read' from the -c command line option instead of standard input.)

Obviously this has certain limitations, like you'd better not write shell scripts using programs that read their standard input as a side effect of other operations (at least not without a '</dev/null' or the like). But as Gaelan Steele noted, it's a very early Unix way to handle the whole thing.

Also, Norman Wilson noted that this is where we get the ':' command to do nothing, which would later be one of the ways of writing comments in shell scripts. However, V6 isn't where either ':' or 'goto' appear; a version of 'goto' can be found as far back as V2's goto.c, and just as in V6 it searches through standard input for a line with ': ' at the start. I believe that ':' was always built in to the Unix shell, making it one of the oldest builtins along with 'chdir' (what eventually became 'cd'), although it's not mentioned in the V3 sh manpage.

(Unfortunately we don't seem to have the source for the V3 shell, and neither source nor manual page for the V2 shell. But I can't imagine early Unix not making ':' a built in command like 'chdir', and we know you could put ':' in shell scripts due to 'goto'.)

Update: To explain the connection between 'goto' and ':' a bit more, how 'goto' worked is that your script did 'goto label' and goto searched through the script for a line that said ': label' (for an arbitrary word as the label) and positioned execution there. In order to make this line valid in a shell script, there was a ':' shell builtin that did nothing.

unix/V6ShellControlFlowII written at 21:38:17;


Page tools: See As Normal.
Search:
Login: Password:

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.