Yesterday I polled people on whether opening /dev/fd/N should act as if you'd dup()'d that file descriptor. The answer is 'no, that's terrifying'.
When you dup() file descriptors, the two fds share a bunch of state, especially including the IO offset in the file; meanwhile, open() promises a file descriptor with independent state. So turning open() into dup() may cause all sorts of fun surprises as changes to the current offset and other things on one fd are magically also on the other.
@lanodan I'm actually a bit curious about whether there's a deep reason for that dup() behavior or if it started as an artifact of an easy implementation (just increase the reference count on a file object in the kernel, no need to copy it and do stuff and etc etc). Especially since early Unixes had small limits on things like total open files; dup()'s sharing reduced pressure on them.
@robryk @lanodan I guess there may be internal kernel state for pipes and so on that assumes the file object will be unique and never duplicated.
(Even if the kernel provides no user-level way to re-open a pipe, it can internally duplicate their file objects.)
PS: It turns out you have to have dup() semantics to make shell pipelines that redirect to/from files work, so my speculation is wrong anyways.
I don't mean that implementation requires that, but that I don't see what semantics you could assign to two independent opens of the same end of the same pipe.
(Actually, the problem is even worse with Unix sockets: server side was not created on request, so you can't really do anything other than moral equivalent of dup; client-side was not created via open() *and* the file/abstract name that was dialed could no longer be accessible.)
Ah, I see, you are proposing something that would still function as the "same open" for all intents and purposes but not share flags (or file pointers, but you mentioned that this would break appending to shared std{out,err}). I think I agree that sharing of O_NONBLOCK and other flags I can think of makes no sense.
I wonder why O_NONBLOCK is a FL-flag and not an FD-flag.