Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/bin/sh



    Date:        Mon, 4 Jan 2016 08:26:29 -0500
    From:        christos%zoulas.com@localhost (Christos Zoulas)
    Message-ID:  <20160104132629.A6EE017FDAD%rebar.astron.com@localhost>

  | 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?



Home | Main Index | Thread Index | Old Index