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 14:41:30 -0500
    From:        christos%zoulas.com@localhost (Christos Zoulas)
    Message-ID:  <20160104194130.6064F17FDAD%rebar.astron.com@localhost>


  | Yes, the issues are:
  | 
  |     - Is leaving descriptors open really needed? I can write the above
  |       example in a way it works...

That one yes, but there are cases where more than one open doesn't work.

  |     - Should portable code rely on open file descriptors across exec, since
  |       it is unspecified behavior?

No, portable code shouldn't, but sometimes we (or at least I) just need
code that works for me, with no intent that it ever be used elsewhere
(and often where no-one else would even conceivably be interested).

If the build system, and the rc scripts, all work with your modified sh, then
clearly they aren't depending upon that behaviour, and in that case,
fixing them to explicitly close the "save for later" fds should not be
difficult (painstaking to actually do perhaps, but not difficult.)

  |     - Should there be away to control this from the shell? And if there
  |       is what should the default be? What should the syntax be?

Control, yes, probably.  The default should be the way NetBSD has
always been.  It isn't a bug, and of itself it isn't a security issue
(though, as always, sloppy code can make security holes), so we should
retain compat with what we have always had, at least as the default case.

Syntax ... no answers right now, a different > operator perhaps (7>&!3 ?)
(would be easiest to convert existing code if it prefers the other way),
or a new built in command to set/reset close on exec on a (set of) fd
(which could also manipulate other fd flags for the shell as well,
not that most of the others would be useful - we could even call it "fcntl")

  | 	- Setup redirections so that stdout and stderr are captured
  | 	- Execute command, where if successful the file descriptors
  | 	  are closed, and if it failed, they are kept open for further
  | 	  processing.

command fd>&- ...

The cmd is run (if it can be) with fd closed.   In the shell, fd remains
open (to be closed later, either explicitly, or upon exit) and if needed
you can do whatever afterwards, including closing fd (or moving it back to
stdout) if the workaround is no longer needed.

Obviously the "command" the redirect is added to needs to be the one
(or parent of the set) where fd is not needed, not just another of the
set of rc scripts/functions.


  | Yup, it works. Nothing would work if it did not.

Really?   How frequently do we do "exec >file" in anything that
is actually used (if the explicit number makes a difference, write
it as "exec 1>file" - those two should be identical).

  | The closeon-exec feature is only for specific redirections 
  | (redirections to specific file numbers).

Yes, understood, but that's what I asked about, when the specific
file number is 1 (or 0 or 2) - I saw nothing in the code that would
prevent close-on-exec being set for them.

I just did your test (as below) again using ksh (NetBSD's /bin/ksh, not
the real one) and sure enough, it fails, when using fd 6.   But if I change
it to use "1" instead of "6", then it works, so clearly ksh is doing
different things depending upon what the fd value happens to be.   I have
no idea how they explain that.

  | I.e. should I expect the following to work?
  | 
  | $ cat test1
  | #!/bin/sh
  | exec 6> out
  | echo "test" >&6
  | sh ./test2
  | exec 6>&-
  | 
  | $ cat test2
  | cat cloexec/test2
  | echo "test2" >&6
  | 
  | $ ./test1

Aside from the "cat cloexec/test2" line, which I suspect might be a pasto
in construction of your mail, otherwise I have no idea what that's about,
then yes, on NetBSD it should work, and should write
	test
	test2
to the file "out".   That's what it does on my system (which does not have
your changed shell) right now.   Unless there is a very good reason, that
is what it should continue to do.

Whether anyone should write code like that, which depends upon it working
that way is a different question, to which the answer is probably, "no",
but sometimes doing it differently is hard - harder than justified by the
requirements.

The place I use exec redirections most is when I really want to write

	while read a b c
	do
		commands
	done < file

which is fine, except when I need the result of "commands" to affect
the state of the shell outside the loop (like variable assignments).
There are some gross hacks that can be used to deal with that, but the
most elegant is to convert it to ...

	exec 9<&0
	exec 0<file
	while read a b c
	do
		commands 9<&-	# intentionally with stdin still from "file"
	done
	exec 0<&9

However, if the definition of "exec 0<" is to set close on exec on 0,
then that is not going to work very well any more.

For what it is worth, just so the example doesn't look a bit unlikely to
be useful, for me, "file" here is often "/dev/tty" -- the script running
this has its stdin directed from elsewhere - a pipe usually - but I need
to interact with the script, and with commands it runs - like "more"
(or less) perhaps.)

kre



Home | Main Index | Thread Index | Old Index