Source-Changes-D archive

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

Re: CVS commit: src/bin/sh



On Jan 5,  4:40am, kre%munnari.OZ.AU@localhost (Robert Elz) wrote:
-- Subject: Re: CVS commit: src/bin/sh

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

Sure, I think that there are examples where the parent/child shells use
fds > 2 to communicate, but with an exec'ed program? Does the exec'ed program
know what to do with fd > 2? Is it hard-coded, or do we specify it with -fd N?
It does not look like this is the common case.

| 
|   |     - 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).

The knob would help for that.

| 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.)

They seem to work fine.

|   |     - 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")

Well, ! means overwrite in re-directions... I am leaning towards the fcntl
builtin solution...

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

Perhaps, if we could do that and re-open with append. I am not sure
what happens with concurrency though.

| 
|   | 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).

These two are identical since 0, 1, 2 fd's are never touched. OTOH
exec 6> foo isn't.

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

The check is in both copyfd() and in the specific fcntl case.

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

I think it still works, since the close happens on the forked child...

| 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.)

Let's see how it goes; if things break I will revert it. So far I don't
see anything broken.

christos


Home | Main Index | Thread Index | Old Index