bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bash clears sa_flags but never restores it for child processes


From: llattanzi+bash
Subject: bash clears sa_flags but never restores it for child processes
Date: Thu, 15 Jul 2004 21:24:50 -0700 (PDT)

Configuration Information [Automatically generated, do not change]:
Machine: powerpc
OS: darwin8.0
Compiler: gcc
Compilation CFLAGS: -arch i386 -arch ppc -g -Os -pipe -no-cpp-precomp -arch i386 -arch ppc -pipe -DPROGRAM='bash' -DCONF_HOSTTYPE='powerpc' -DCONF_OSTYPE='darwin8.0' -DCONF_MACHTYPE='powerpc-apple-darwin8.0' -DCONF_VENDOR='apple' -DSHELL -DHAVE_CONFIG_H -DMACOSX -I. -I/SourceCache/bash/bash-32/bash -I/SourceCache/bash/bash-32/bash/include -I/SourceCache/bash/bash-32/bash/lib -arch i386 -arch ppc -g -Os -pipe -no-cpp-precomp -arch i386 -arch ppc -pipe uname output: Darwin stderr.apple.com 8.0.0b1 Darwin Kernel Version 8.0.0b1: Mon Jul 12 21:41:56 PDT 2004; root:xnu/xnu-638.1.obj~4/RELEASE_PPC Power Macintosh powerpc
Machine Type: powerpc-apple-darwin8.0

Bash Version: 2.05b
Patch Level: 0
Release Status: release

Description:
        Child processes that receive signals start seeing EINTR on
        i/o system calls

Repeat-By:
        Run the following under bash and other shells. Also gdb it, run and
        hit ^c, then cont. Notice the perror output
#include <stdio.h>
#include <sys/signal.h>

int main() {
        struct sigaction oact;
        int i;
        for (i = 1; i < NSIG; i++) {
                memset(&oact, 0, sizeof(oact));
                sigaction(i, NULL, &oact);
                printf("Sig:%d\tFlags:0x%x\n", i, oact.sa_flags);
        }
        if (read(0, &i, 1) < 0) {
                perror("read");
                exit(1);
        }
        exit(0);
}

Fix:
Index: bash/bash/sig.c
diff -u bash/bash/sig.c:1.1.1.4 bash/bash/sig.c:1.1.1.4.24.2
--- bash/bash/sig.c:1.1.1.4     Sat Apr  5 00:00:26 2003
+++ bash/bash/sig.c     Thu Jul 15 21:24:53 2004
@@ -222,7 +222,8 @@
       /* If we've already trapped it, don't do anything. */
       if (signal_is_trapped (XSIG (i)))
        continue;
-
+      sigaction (XSIG (i), 0, &oact);
+      act.sa_flags = oact.sa_flags; /* preserve sa_flags */
       sigaction (XSIG (i), &act, &oact);
       XHANDLER(i) = oact.sa_handler;
       /* Don't do anything with signals that are ignored at shell entry
@@ -303,7 +304,6 @@
     return;

 #if defined (HAVE_POSIX_SIGNALS)
-  act.sa_flags = 0;
   sigemptyset (&act.sa_mask);
   for (i = 0; i < TERMSIGS_LENGTH; i++)
     {
@@ -311,8 +311,9 @@
         trap code will restore the correct value. */
       if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
        continue;
-
+      sigaction(XSIG(i), 0, &act); /* set sa_flags */
       act.sa_handler = XHANDLER (i);
+      sigemptyset (&act.sa_mask);
       sigaction (XSIG (i), &act, (struct sigaction *) NULL);
     }
 #else /* !HAVE_POSIX_SIGNALS */
@@ -502,8 +503,8 @@
 {
   struct sigaction act, oact;

+  sigaction(sig, 0, &act); /* set sa_flags */
   act.sa_handler = handler;
-  act.sa_flags = 0;
 #if 0
   if (sig == SIGALRM)
     act.sa_flags |= SA_INTERRUPT;      /* XXX */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]