henry (11/25/82)
Dup() and dup2() are unaware of the u_pofile array, which contains (at the moment) the close-on-exec flags for the file descriptors. Dup() always returns a stays-open-on-exec descriptor, since ufalloc() zeros out the u_pofile slot for the descriptor it returns. Now comes the fun part! Dup2() does not use ufalloc(), so the descriptor it gives back simply inherits the previous value of the u_pofile entry. This is lots of fun, because close() does not zero out u_pofile! Nor does exec()! Even the code for exec() that does handle u_pofile -- the close-on-exec handling -- gets it wrong: it clears only the close-on-exec bit, not the whole word. All of this would be much more serious if there were more useful bits in u_pofile. As it is, it's not surprising that nobody noticed. The fix should be fairly straightforward, although I have *not* tested it. The code in sys3.c that implements dup() and dup2() should carry the u_pofile contents along with the descriptor when duplicating it. I think I would also be inclined to zero out the u_pofile entry when the descriptor is closed, just in case.