From d5c2daef10de69002c6ab34bdcf1b707da2097b6 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Thu, 12 Apr 2001 09:10:24 +0000 Subject: [PATCH] switch to using /proc//status on Linux --- signal.c | 96 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/signal.c b/signal.c index 6051d8ff..4a676a19 100644 --- 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) -- 2.40.0