Blame stdio-common/psiginfo.c

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