Date: Mon, 4 Jan 2016 08:26:29 -0500 From: chris...@zoulas.com (Christos Zoulas) Message-ID: <20160104132629.a6ee017f...@rebar.astron.com>
| Ksh does it and it works... I must have been too aggressive. It isn't a matter of whether it can be made to work or not for NetBSD's build system, or whether you have hodden a bug in the rc scripts (I'll explain why "hidden" rather than "fixed" below) but of what is right. In the test case you included in the commit log, I expect the echo in test2 to work, and write to file "out" the way NetBSD's sh (and all Bourne shell variants, since the first one) have always done. That is, the shell code exec 3>&1 cmd is (and always was intended to be) the same as the (abbreviated) C code dup2(1, 3); if (fork() == 0) execlp("cmd", "cmd", (char *)0); else wait(&status); The case you use "exec 6>out" is similar, but messier to write directly in C because there's no "open_giving_fd_n()" function, so it needs an open/dup2/close sequence, so I'll omit that one (I'd probably get it wrong...). The effect should be the same however. If I wanted fd 6 closed when test2 was run in your example, I'd write the line that runs it as ... sh ./test2 6>&- We know fd 6 is open at that point, the "exec >&6" is there explicitly, and the close hasn't happened yet. Now I know that POSIX says you're allowed to do it the way you have changed it to, but that's only because ksh (for whatever reason) decided to change the semantics, and what ksh does seems to have inordinate sway with the posix shell people... But, they say ... it is unspecified whether those file descriptors remain open when the shell invokes another utility so the way that NetBSD's shell (and Bourne shells in general) have always done it is just as valid. That's why you haven't "fixed" anything in the rc system by the change. What you have done is made it rely upon (your version of) NetBSD's implementation of that unspecified operation. Take the scripts to any other (rational) system and the bug (if there is one) would reappear. On NetBSD the bug will be hidden, which makes it one of more insidious type. If there is a bug there, it should be fixed in the scripts (by explicitly closing fd's that have been opened using exec when they are not needed). The "if" is not because I believe the daemons you showed need, or want, to have those fds open, but because the rc scripts are complex, and I have not analysed them to determine whether they are relying upon the "keep open through exec" behaviour for some reason. And yes, that would also be relying on unspecified behaviour, but it is at least the ancient historic behaviour, where it is very hard to code correctly in any sane way if close_on_exec is forced on when it is not wanted (whereas it is trivial to close fds that have been opened but are not wanted). kre ps: have you tested the shell with your change to make sure that exec >outfile followed by cmd1; cmd2; cmd3 doesn't run those commands with stdout closed?