mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			204 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (C) 2009-2012 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
 | 
						|
   <http://www.gnu.org/licenses/>.  */
 | 
						|
 | 
						|
#include <errno.h>
 | 
						|
#include <libintl.h>
 | 
						|
#include <signal.h>
 | 
						|
#include <stdint.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <not-cancel.h>
 | 
						|
 | 
						|
 | 
						|
#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 = sizeof (C (codes_, sig)) / sizeof (C (codes_, sig)[0]);\
 | 
						|
	  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_not_cancel (STDERR_FILENO, buf, strlen (buf));
 | 
						|
}
 |