/* Copyright (C) 2009-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ #include #include #include #include #include #include #include #include #include #include #define MF(l) MF1 (l) #define MF1(l) str_##l #define C(s1, s2) C1 (s1, s2) #define C1(s1, s2) s1##s2 #define NOW SIGILL #include "psiginfo-define.h" #define NOW SIGFPE #include "psiginfo-define.h" #define NOW SIGSEGV #include "psiginfo-define.h" #define NOW SIGBUS #include "psiginfo-define.h" #define NOW SIGTRAP #include "psiginfo-define.h" #define NOW SIGCLD #include "psiginfo-define.h" #define NOW SIGPOLL #include "psiginfo-define.h" /* Print out on stderr a line consisting of the test in S, a colon, a space, a message describing the meaning of the signal number PINFO and a newline. If S is NULL or "", the colon and space are omitted. */ void psiginfo (const siginfo_t *pinfo, const char *s) { char buf[512]; FILE *fp = __fmemopen (buf, sizeof (buf), "w"); if (fp == NULL) { const char *colon; if (s == NULL || *s == '\0') s = colon = ""; else colon = ": "; __fxprintf (NULL, "%s%ssignal %d\n", s, colon, pinfo->si_signo); return; } if (s != NULL && *s != '\0') fprintf (fp, "%s: ", s); const char *desc; if (pinfo->si_signo >= 0 && pinfo->si_signo < NSIG && ((desc = _sys_siglist[pinfo->si_signo]) != NULL #ifdef SIGRTMIN || (pinfo->si_signo >= SIGRTMIN && pinfo->si_signo < SIGRTMAX) #endif )) { #ifdef SIGRTMIN if (desc == NULL) { if (pinfo->si_signo - SIGRTMIN < SIGRTMAX - pinfo->si_signo) { if (pinfo->si_signo == SIGRTMIN) fprintf (fp, "SIGRTMIN ("); else fprintf (fp, "SIGRTMIN+%d (", pinfo->si_signo - SIGRTMIN); } else { if (pinfo->si_signo == SIGRTMAX) fprintf (fp, "SIGRTMAX ("); else fprintf (fp, "SIGRTMAX-%d (", SIGRTMAX - pinfo->si_signo); } } else #endif fprintf (fp, "%s (", _(desc)); const char *base = NULL; const uint8_t *offarr = NULL; size_t offarr_len = 0; switch (pinfo->si_signo) { #define H(sig) \ case sig: \ base = C(codestrs_, sig).str; \ offarr = C (codes_, sig); \ offarr_len = array_length (C (codes_, sig)); \ break H (SIGILL); H (SIGFPE); H (SIGSEGV); H (SIGBUS); H (SIGTRAP); H (SIGCHLD); H (SIGPOLL); } const char *str = NULL; if (offarr != NULL && pinfo->si_code >= 1 && pinfo->si_code <= offarr_len) str = base + offarr[pinfo->si_code - 1]; else switch (pinfo->si_code) { case SI_USER: str = N_("Signal sent by kill()"); break; case SI_QUEUE: str = N_("Signal sent by sigqueue()"); break; case SI_TIMER: str = N_("Signal generated by the expiration of a timer"); break; case SI_ASYNCIO: str = N_("\ Signal generated by the completion of an asynchronous I/O request"); break; case SI_MESGQ: str = N_("\ Signal generated by the arrival of a message on an empty message queue"); break; #ifdef SI_TKILL case SI_TKILL: str = N_("Signal sent by tkill()"); break; #endif #ifdef SI_ASYNCNL case SI_ASYNCNL: str = N_("\ Signal generated by the completion of an asynchronous name lookup request"); break; #endif #ifdef SI_SIGIO case SI_SIGIO: str = N_("\ Signal generated by the completion of an I/O request"); break; #endif #ifdef SI_KERNEL case SI_KERNEL: str = N_("Signal sent by the kernel"); break; #endif } if (str != NULL) fprintf (fp, "%s ", _(str)); else fprintf (fp, "%d ", pinfo->si_code); if (pinfo->si_signo == SIGILL || pinfo->si_signo == SIGFPE || pinfo->si_signo == SIGSEGV || pinfo->si_signo == SIGBUS) fprintf (fp, "[%p])\n", pinfo->si_addr); else if (pinfo->si_signo == SIGCHLD) fprintf (fp, "%ld %d %ld)\n", (long int) pinfo->si_pid, pinfo->si_status, (long int) pinfo->si_uid); else if (pinfo->si_signo == SIGPOLL) fprintf (fp, "%ld)\n", (long int) pinfo->si_band); else fprintf (fp, "%ld %ld)\n", (long int) pinfo->si_pid, (long int) pinfo->si_uid); } else fprintf (fp, _("Unknown signal %d\n"), pinfo->si_signo); fclose (fp); __write_nocancel (STDERR_FILENO, buf, strlen (buf)); }