Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #14902 > unrolled thread

Re: write() not retried after EINTR in printf and echo

Started byPusillanimous Pussyfooter <0xef967c36@gmail.com>
First post2018-12-09 19:45 +0200
Last post2018-12-09 19:45 +0200
Articles 1 — 1 participant

Back to article view | Back to gnu.bash.bug


Contents

  Re: write() not retried after EINTR in printf and echo Pusillanimous Pussyfooter <0xef967c36@gmail.com> - 2018-12-09 19:45 +0200

#14902 — Re: write() not retried after EINTR in printf and echo

FromPusillanimous Pussyfooter <0xef967c36@gmail.com>
Date2018-12-09 19:45 +0200
SubjectRe: write() not retried after EINTR in printf and echo
Message-ID<mailman.5482.1544390346.1284.bug-bash@gnu.org>
> There are a couple of signals for which this is the appropriate behavior.
> The right fix is to install handlers with the SA_RESTART flag set. The
> next version of bash will install its SIGWINCH handler with SA_RESTART.

Here is a trivial patch doing just that, though IMHO it would be much better
and more consistent to check for EINTR and restart the write() system call,
as it's already done for open() in redir.c:redir_open(). The EINTR "error"
should never be user visible, no matter what signal had caused it.

The problem could also be reproduced with

	printf '%065535d' 1 | sleep 10000

followed by a terminal resize, but not with

	mkfifo /tmp/fifo; exec 7</tmp/fifo

because the EINTR is handled correctly in redir_open().

diff --git a/sig.c b/sig.c
index e5bb7399..cc2456c5 100644
--- a/sig.c
+++ b/sig.c
@@ -736,12 +736,17 @@ set_signal_handler (sig, handler)
   /* We don't want a child death to interrupt interruptible system calls, even
      if we take the time to reap children */
 #if defined (SIGCHLD)
   if (sig == SIGCHLD)
     act.sa_flags |= SA_RESTART;		/* XXX */
 #endif
+  /* And neither should a terminal resize */
+#if defined (SIGWINCH)
+  if (sig == SIGWINCH)
+    act.sa_flags |= SA_RESTART;		/* XXX */
+#endif
   /* If we're installing a SIGTERM handler for interactive shells, we want
      it to be as close to SIG_IGN as possible. */
   if (sig == SIGTERM && handler == sigterm_sighandler)
     act.sa_flags |= SA_RESTART;		/* XXX */
 
   sigemptyset (&act.sa_mask);

[toc] | [standalone]


Back to top | Article view | gnu.bash.bug


csiph-web