]> git.tue.mpg.de Git - paraslash.git/commit
stdin/stdout: Only set nonblock flags for non-tty fds.
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 30 Jul 2017 21:11:38 +0000 (23:11 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sat, 5 Aug 2017 12:46:31 +0000 (14:46 +0200)
commit86595f65b445fb587489c863e93ad2b2337d7497
treeb25a31cad8a0e3dd4247b064e5c9819be34366b4
parentce9c411a5bee664ea2bbe5d4614b81830a14a41b
stdin/stdout: Only set nonblock flags for non-tty fds.

Although the ->post_select methods of all paraslash executables perform
I/O only when select(2) reports that the file descriptor is ready,
we set the O_NONBLOCK flag for all monitored fds. This is considered
good practice because, in general, it might happen that a subsequent
read(2) call blocks even if select(2) indicates that the fd is ready
for reading. For example, an fd corresponding to a TCP socket might
be flagged as ready for reading if a network packet with incorrect
checksum has arrived, but a subsequent read(2) blocks until the packet
has been retransmitted.

However, stdin and stdout often correspond to a terminal device where
the above scenario won't happen. Moreover, for terminals it's essential
to reset the O_NONBLOCK flag to the old value on exit because the
shell refers to the same file description and thus shares the file
status flags, including O_NONBLOCK. Many terminal applications, for
example dialog(1), expect stdout to be set to blocking mode and fail
in arcane ways if O_NONBLOCK is set.

When the stdin and stdout tasks are about to exit, they reset the
file status flags back to the original values. However if "para_client
stat" is killed with SIGINT, SIGTERM or SIGKILL, or put to sleep with
SIGSTOP, the O_NONBLOCK flag remains set because para_client does not
handle signals at all. para_recv, para_filter and para_write suffer
from the same issue. Adding signal handling to these programs would
not help in the SIGSTOP case because this signal can not be caught.

This patch modifies stdin.c and stdout.c to no longer set O_NONBLOCK
for fd 0 and fd 1 if these fds are associated with a terminal
device. This is much easier and should do the job as well.
stdin.c
stdout.c