I still try to digest your explanations. I thought, that processes
just do something like dup()'ing the file descriptors of their
terminal but after some strace experiments, I think that is totally
wrong.
Actually, the way that descriptors are inherited by a fork()ed process is
akin to dup(). In particular, any descriptors which refer to a
random-access stream (anything which supports lseek(), i.e. a file or
block device) share a single file position, so lseek()ing on a descriptor
will affect the file position for any copies of that stream created by
dup(), dup2() or fork(); the only way to get a stream with its own
position is to open() the file (etc) again. Likewise for the file
status flags (O_APPEND, O_NONBLOCK, etc). However, a "cloned" descriptor
gets its own copy of the file descriptor flags (i.e. the FD_CLOEXEC flag).
open()ing the /proc/<pid>/fd/<n> pseudo-files is a bit of a hack, and
Linux-specific. The behaviour is a cross between the fork/dup behaviour
and a separate open() operation. Opening a descriptor which refers to a
pipe opens the "correct" end based upon the mode (read or write), as with
a normal open(), but the resulting descriptor shares its file position and
status flags, as with fork/dup.
I'd like to learn more about this (how processes, their controlling
terminals and the std file descriptors relate)
There's nothing special about the standard descriptors. A child process
inherits all of its parent's descriptors. If the parent has closed any of
its standard descriptors, they'll still be closed in the child
(one exception: Linux will force these descriptors to be open when
executing a setuid executable to avoid potential security issues).
Also, the controlling terminal is unrelated to the standard descriptors.
Upon login, a terminal will typically be assigned as both the controlling
terminal and all three standard descriptors, but they may diverge after
that. E.g. if you start a pipeline ("foo | bar | baz") from the shell,
some of the standard descriptors will be replaced by pipes, but the
controlling terminal will be unaffected. The controlling terminal relates
primarily to signals (Ctrl-C, Ctrl-Z, etc) and job control.
Do you know any links to deeper material (tried Google but what I've
found is to shallow)
I don't have any links. If you want to understand the core Unix API, the
best reference I know of is Stevens ("Advanced Programming in the Unix
Environment", by W. Richard Stevens). Unfortunately, it's not cheap.
In spite of the title, it doesn't assume any prior Unix knowledge; the
"Advanced" mainly refers to the fact that it's the opposite of the "Learn
X in Five Minutes" books, i.e. it's thorough. That's how it comes to >700
pages while only covering the core API (files, processes, and terminals;
no sockets, no X, no I18N, ...).