(root)/
glibc-2.38/
stdio-common/
psiginfo.c
       1  /* Copyright (C) 2009-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <array_length.h>
      19  #include <errno.h>
      20  #include <libintl.h>
      21  #include <signal.h>
      22  #include <stdint.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <string.h>
      26  #include <unistd.h>
      27  #include <not-cancel.h>
      28  
      29  
      30  #define MF(l) MF1 (l)
      31  #define MF1(l) str_##l
      32  #define C(s1, s2) C1 (s1, s2)
      33  #define C1(s1, s2) s1##s2
      34  
      35  #define NOW SIGILL
      36  #include "psiginfo-define.h"
      37  
      38  #define NOW SIGFPE
      39  #include "psiginfo-define.h"
      40  
      41  #define NOW SIGSEGV
      42  #include "psiginfo-define.h"
      43  
      44  #define NOW SIGBUS
      45  #include "psiginfo-define.h"
      46  
      47  #define NOW SIGTRAP
      48  #include "psiginfo-define.h"
      49  
      50  #define NOW SIGCLD
      51  #include "psiginfo-define.h"
      52  
      53  #define NOW SIGPOLL
      54  #include "psiginfo-define.h"
      55  
      56  
      57  /* Print out on stderr a line consisting of the test in S, a colon, a space,
      58     a message describing the meaning of the signal number PINFO and a newline.
      59     If S is NULL or "", the colon and space are omitted.  */
      60  void
      61  psiginfo (const siginfo_t *pinfo, const char *s)
      62  {
      63    char buf[512];
      64    FILE *fp = __fmemopen (buf, sizeof (buf), "w");
      65    if (fp == NULL)
      66      {
      67        const char *colon;
      68  
      69        if (s == NULL || *s == '\0')
      70  	s = colon = "";
      71        else
      72  	colon = ": ";
      73  
      74        __fxprintf (NULL, "%s%ssignal %d\n", s, colon, pinfo->si_signo);
      75        return;
      76      }
      77  
      78    if (s != NULL && *s != '\0')
      79      fprintf (fp, "%s: ", s);
      80  
      81    const char *desc;
      82    if (pinfo->si_signo >= 0 && pinfo->si_signo < NSIG
      83        && ((desc = __sys_siglist[pinfo->si_signo]) != NULL
      84  #ifdef SIGRTMIN
      85  	  || (pinfo->si_signo >= SIGRTMIN && pinfo->si_signo < SIGRTMAX)
      86  #endif
      87  	 ))
      88      {
      89  #ifdef SIGRTMIN
      90        if (desc == NULL)
      91  	{
      92  	  if (pinfo->si_signo - SIGRTMIN < SIGRTMAX - pinfo->si_signo)
      93  	    {
      94  	      if (pinfo->si_signo == SIGRTMIN)
      95  		fprintf (fp, "SIGRTMIN (");
      96  	      else
      97  		fprintf (fp, "SIGRTMIN+%d (", pinfo->si_signo - SIGRTMIN);
      98  	    }
      99  	  else
     100  	    {
     101  	      if (pinfo->si_signo == SIGRTMAX)
     102  		fprintf (fp, "SIGRTMAX (");
     103  	      else
     104  		fprintf (fp, "SIGRTMAX-%d (", SIGRTMAX - pinfo->si_signo);
     105  	    }
     106  	}
     107        else
     108  #endif
     109  	fprintf (fp, "%s (", _(desc));
     110  
     111        const char *base = NULL;
     112        const uint8_t *offarr = NULL;
     113        size_t offarr_len = 0;
     114        switch (pinfo->si_signo)
     115  	{
     116  #define H(sig) \
     117  	case sig:							      \
     118  	  base = C(codestrs_, sig).str;					      \
     119  	  offarr = C (codes_, sig);					      \
     120  	  offarr_len = array_length (C (codes_, sig));			      \
     121  	  break
     122  
     123  	  H (SIGILL);
     124  	  H (SIGFPE);
     125  	  H (SIGSEGV);
     126  	  H (SIGBUS);
     127  	  H (SIGTRAP);
     128  	  H (SIGCHLD);
     129  	  H (SIGPOLL);
     130  	}
     131  
     132        const char *str = NULL;
     133        if (offarr != NULL
     134  	  && pinfo->si_code >= 1 && pinfo->si_code <= offarr_len)
     135  	str = base + offarr[pinfo->si_code - 1];
     136        else
     137  	switch (pinfo->si_code)
     138  	  {
     139  	  case SI_USER:
     140  	    str = N_("Signal sent by kill()");
     141  	    break;
     142  	  case SI_QUEUE:
     143  	    str = N_("Signal sent by sigqueue()");
     144  	    break;
     145  	  case SI_TIMER:
     146  	    str = N_("Signal generated by the expiration of a timer");
     147  	    break;
     148  	  case SI_ASYNCIO:
     149  	    str = N_("\
     150  Signal generated by the completion of an asynchronous I/O request");
     151  	    break;
     152  	  case SI_MESGQ:
     153  	    str = N_("\
     154  Signal generated by the arrival of a message on an empty message queue");
     155  	    break;
     156  #ifdef SI_TKILL
     157  	  case SI_TKILL:
     158  	    str = N_("Signal sent by tkill()");
     159  	    break;
     160  #endif
     161  #ifdef SI_ASYNCNL
     162  	  case SI_ASYNCNL:
     163  	    str = N_("\
     164  Signal generated by the completion of an asynchronous name lookup request");
     165  	    break;
     166  #endif
     167  #ifdef SI_SIGIO
     168  	  case SI_SIGIO:
     169  	    str = N_("\
     170  Signal generated by the completion of an I/O request");
     171  	    break;
     172  #endif
     173  #ifdef SI_KERNEL
     174  	  case SI_KERNEL:
     175  	    str = N_("Signal sent by the kernel");
     176  	    break;
     177  #endif
     178  	  }
     179  
     180        if (str != NULL)
     181  	fprintf (fp, "%s ", _(str));
     182        else
     183  	fprintf (fp, "%d ", pinfo->si_code);
     184  
     185        if (pinfo->si_signo == SIGILL || pinfo->si_signo == SIGFPE
     186  	  || pinfo->si_signo == SIGSEGV || pinfo->si_signo == SIGBUS)
     187  	fprintf (fp, "[%p])\n", pinfo->si_addr);
     188        else if (pinfo->si_signo == SIGCHLD)
     189  	fprintf (fp, "%ld %d %ld)\n",
     190  		 (long int) pinfo->si_pid, pinfo->si_status,
     191  		 (long int) pinfo->si_uid);
     192        else if (pinfo->si_signo == SIGPOLL)
     193  	fprintf (fp, "%ld)\n", (long int) pinfo->si_band);
     194        else
     195  	fprintf (fp, "%ld %ld)\n",
     196  		 (long int) pinfo->si_pid, (long int) pinfo->si_uid);
     197      }
     198    else
     199      fprintf (fp, _("Unknown signal %d\n"),  pinfo->si_signo);
     200  
     201    fclose (fp);
     202  
     203    __write_nocancel (STDERR_FILENO, buf, strlen (buf));
     204  }