O_NONBLOCK on stdin left set by child (using ash shell)

Johns Daniel johns.daniel at gmail.com
Tue Nov 10 18:33:06 UTC 2009


On Tue, Nov 10, 2009 at 11:41 AM, Denys Vlasenko
<vda.linux at googlemail.com> wrote:
> On Tue, Nov 10, 2009 at 5:43 PM, Johns Daniel <johns.daniel at gmail.com> wrote:
>> We just upgraded to BusyBox v1.14.4 (w/ built-in ash shell),
>
> ...where ash got a workaround to not require O_NONBLOCK
> to be cleared on stdin (it used to reset it)...
>
>> and we
>> have noticed what seems to be a bug.
>
> Yes, this is a design bug *in Unix API*. O_NONBLOCK had to be
> a flag associated with a file descriptor, not a file,
> like FD_CLOEXEC.
>
> Or it should be possible to use recv(fd, buf, size, MSG_DONTWAIT)
> on non-sockets.
>
>> When we exit from one of our user apps that sets stdin to O_NONBLOCK,
>> O_NONBLOCK remains set on stdin in the shell. So, any subsequent app
>> not expecting O_NONBLOCK on stdin gets an unexpected EAGAIN. For
>> example,
>
> How ash can know that it was not your *intention* to switch
> O_NONBLOCK ob by one app and use it by other app?
>

It seems to me that it would be bad design to have such an intent.
IOW, one app is changing the *parent shell* in order to pass a
non-standard state on to the next app.

The shell needs to be shared by many apps in the system. So, to work
around the Unix issue, I think the shell should default to a "standard
environment" each time it spawns a new app. If the new app wants
O_NONBLOCK, then it should set it.

My guess is that this is how most shells behave. I could be wrong; I
might be missing some corner cases.

Assuming we don't care about one app passing O_NONBLOCK to another
app, are either of our patches a good solution to the problem?

> --
> vda
>

-- Johns


More information about the busybox mailing list