]> granicus.if.org Git - strace/commitdiff
switch to using /proc/<pid>/status on Linux
authorWichert Akkerman <wichert@deephackmode.org>
Thu, 12 Apr 2001 09:10:24 +0000 (09:10 +0000)
committerWichert Akkerman <wichert@deephackmode.org>
Thu, 12 Apr 2001 09:10:24 +0000 (09:10 +0000)
signal.c

index 6051d8ff144ee738e505461ac6cf39d24f8d887e..4a676a19d1471bd83208139537e27925dd6bbce1 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -378,40 +378,81 @@ int sig;
 #ifdef LINUX
        int sfd;
        char sname[32];
-       char buf[1024];
+       char buf[2048];
        char *s;
        int i;
-       unsigned int signalled, blocked, ignored, caught;
+       /* We also need to handle RT signals */
+       unsigned long long signalled, blocked, ignored, caught;
+#endif
+#ifdef SVR4
+       /*
+        * Since procfs doesn't interfere with wait I think it is safe
+        * to punt on this question.  If not, the information is there.
+        */
+       return 1;
+#else /* !SVR4 */
+       switch (sig) {
+       case SIGCONT:
+       case SIGSTOP:
+       case SIGTSTP:
+       case SIGTTIN:
+       case SIGTTOU:
+       case SIGCHLD:
+       case SIGIO:
+#if defined(SIGURG) && SIGURG != SIGIO
+       case SIGURG:
+#endif
+       case SIGWINCH:
+               /* Gloria Gaynor says ... */
+               return 1;
+       default:
+               break;
+       }
+#endif /* !SVR4 */
+#ifdef LINUX
 
        /* This is incredibly costly but it's worth it. */
-       sprintf(sname, "/proc/%d/stat", tcp->pid);
+       /* NOTE: LinuxThreads internally uses SIGRTMIN, SIGRTMIN + 1 and
+          SIGRTMIN + 2, so we can't use the obsolete /proc/%d/stat which
+          doesn't handle real-time signals). */
+       sprintf(sname, "/proc/%d/status", tcp->pid);
        if ((sfd = open(sname, O_RDONLY)) == -1) {
                perror(sname);
                return 1;
        }
-       i = read(sfd, buf, 1024);
+       i = read(sfd, buf, sizeof(buf));
        buf[i] = '\0';
        close(sfd);
        /*
-        * Skip the extraneous fields. This loses if the
+        * Skip the extraneous fields. We need to skip
         * command name has any spaces in it.  So be it.
         */
-       for (i = 0, s = buf; i < 30; i++) {
-               while (*++s != ' ') {
-                       if (!*s)
-                               break;
-               }
-       }
-       if (sscanf(s, "%u%u%u%u",
-                  &signalled, &blocked, &ignored, &caught) != 4) {
-               fprintf(stderr, "/proc/pid/stat format error\n");
+       s = strstr(buf, "SigPnd:\t");
+
+       if (!s)
+       {
+               fprintf(stderr, "/proc/pid/status format error\n");
                return 1;
        }
+
+       while (*s && *s++ != '\t')
+               ;
+       s += sscanf(s, "%qx", &signalled);
+       while (*s && *s++ != '\t')
+               ;
+       s += sscanf(s, "%qx", &blocked);
+       while (*s && *s++ != '\t')
+               ;
+       s += sscanf(s, "%qx", &ignored);
+       while (*s && *s++ != '\t')
+               ;
+       s += sscanf(s, "%qx", &caught);
+
 #ifdef DEBUG
        fprintf(stderr, "sigs: %08x %08x %08x %08x\n",
                signalled, blocked, ignored, caught);
 #endif
-       if ((ignored & sigmask(sig)) || (caught & sigmask(sig)))
+       if ((ignored & (1ULL << sig)) || (caught & (1ULL << sig)))
                return 1;
 #endif /* LINUX */
 
@@ -426,32 +467,7 @@ int sig;
                return 1;
 #endif /* SUNOS4 */
 
-#ifdef SVR4
-       /*
-        * Since procfs doesn't interfere with wait I think it is safe
-        * to punt on this question.  If not, the information is there.
-        */
-       return 1;
-#else /* !SVR4 */
-       switch (sig) {
-       case SIGCONT:
-       case SIGSTOP:
-       case SIGTSTP:
-       case SIGTTIN:
-       case SIGTTOU:
-       case SIGCHLD:
-       case SIGIO:
-#if defined(SIGURG) && SIGURG != SIGIO
-       case SIGURG:
-#endif
-       case SIGWINCH:
-               /* Gloria Gaynor says ... */
-               return 1;
-       default:
-               break;
-       }
        return 0;
-#endif /* !SVR4 */
 }
 
 #if defined(SUNOS4) || defined(FREEBSD)