You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is no need for stdin_fd and stdout_fd to be distinct file
descriptors, so long as the code is careful to not close a file
descriptor that is still in use. This extra care allows for close() to
be used in preference to shutdown(), unless the same socket is being
used for both stdin and stdout. close() has the advantage that it does
not interfere with other users of the same file description, which
allows the "was this inherited from another process?" hack to be
eliminated. Instead, use the file descriptor number to determine
whether blocking mode needs to be restored - it only needs to be
restored for inherited file descriptors.
To avoid lots of error-prone boilerplate, use a single function to close
stdin_fd or stdout_fd, and wrap it with macros that select the right one
to use. These macros also pass the correct argument for shutdown(2) and
set the just-closed FD to -1, eliminating a nasty potential source of
bugs. The function automatically chooses between close(2) and
shutdown(2) based on whether the two file descriptor arguments it is
passed are identical, ensuring that shutdown(2) is only used if needed.
Furthermore, the function knows (based on the file descriptor number) if
the file descriptor was inherited from another process, and therefore
whether it needs to be restored to blocking mode.
This also avoids making a file descriptor blocking while still in use.
Since the code now knows if stdin and stdout use the same file
descriptor, it can avoid setting the blocking flag on a file descriptor
that is still in use, which could cause a deadlock. This works in every
case except where both stdin and stdout are passed from a parent process
and share a file description.
git blame points to commit 0802df7
("Factor out process_child_io"), but I suspect the actual bug dates back
as far as the introduction of socket-based services in
76697e3 ("Working socket-based qrexec").
0 commit comments