msh stdin, fcntl nonblock on stdin by child of child
Denys Vlasenko
vda.linux at googlemail.com
Wed Feb 20 19:48:09 UTC 2008
On Wednesday 20 February 2008 17:39, Jate Sujjavanich wrote:
> I run a script in the background which starts dropbear client. Dropbear
> sets stdin to non-blocking. This causes my msh shell in the foreground
> to print infinite prompts because lineedit is expecting a blocking read
> (in safe_read).
>
> msh -> sh spawn_dbclient & -> dbclient args
>
> Should dbclient's fcntl be affecting msh's stdin?
Yes. This is a design bug in UNIX API.
fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NONBLOCK);
will set nonblocking mode not only on _your_
stdin, but also on stdin of your parent, etc.
In general,
fd2 = dup(fd1);
fcntl(fd2, F_SETFL, fcntl(fd2, F_GETFL, 0) | O_NONBLOCK);
sets both fd1 and fd2 to O_NONBLOCK. This includes cases
where duping is done implicitly by fork() etc.
We need
fcntl(fd2, F_SETFD, fcntl(fd2, F_GETFD, 0) | O_NONBLOCK);
(note SETFD, not SETFL!) but such thing doesn't exist.
Alternatively, we need nonblocking_read(fd, ...) which doesn't
require O_NONBLOCK dance at all. Actually, it exists:
n = recv(fd, buf, len, MSG_DONTWAIT);
MSG_DONTWAIT
Enables non-blocking operation; if the operation
would block, EAGAIN is returned.
but recv() works only for sockets!!! DAMN.
--
vda
More information about the busybox
mailing list