Argh, I'm being a complete numpty. I had forgotten that there are
always two file descriptors here.
The shell obviously gets 0, 1 & 2 as standard, and we're telling the
shell to open /proc/self/fd/3 - which equates to an fd 3 that we're
leaving open for itself. So the shell is exec()d with:
0 <- stdin
1 -> stdout
2 -> stderr
3 <- upstart
The shell still has to open() /proc/self/fd/3, which gives it a new
file descriptor (10). This points to the same underlying "file" and is
equivalent to as if it had just dup()d 3. So now:
3 and 10 connect to the same underlying file, so it doesn't matter if
the shell closes 3 - the very fact it's read the "exec 3<&-" line
means that it must have opened the file and be reading from it on fd
10. So closing 3 is just cleaning up after a dup().
So if the first line of all passed in scripts was "exec 3<&-", after
that line, the shell would have:
It still has the pipe to upstart open, it's just on a different fd and
not visible to sub-processes -- if you'd done ls /proc/$$/fd you would
still see it ;-)
Argh, I'm being a complete numpty. I had forgotten that there are
always two file descriptors here.
The shell obviously gets 0, 1 & 2 as standard, and we're telling the
shell to open /proc/self/fd/3 - which equates to an fd 3 that we're
leaving open for itself. So the shell is exec()d with:
0 <- stdin
1 -> stdout
2 -> stderr
3 <- upstart
The shell still has to open() /proc/self/fd/3, which gives it a new
file descriptor (10). This points to the same underlying "file" and is
equivalent to as if it had just dup()d 3. So now:
0 <- stdin
1 -> stdout
2 -> stderr
3 <- upstart
10 <- upstart (reading from, FD_CLOEXEC)
3 and 10 connect to the same underlying file, so it doesn't matter if
the shell closes 3 - the very fact it's read the "exec 3<&-" line
means that it must have opened the file and be reading from it on fd
10. So closing 3 is just cleaning up after a dup().
So if the first line of all passed in scripts was "exec 3<&-", after
that line, the shell would have:
0 <- stdin
1 -> stdout
2 -> stderr
10 <- upstart (reading from, FD_CLOEXEC)
It still has the pipe to upstart open, it's just on a different fd and
not visible to sub-processes -- if you'd done ls /proc/$$/fd you would
still see it ;-)