⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strsignal.c

📁 早期freebsd实现
💻 C
字号:
/* Extended support for using signal values.   Copyright (C) 1992 Free Software Foundation, Inc.   Written by Fred Fish.  fnf@cygnus.comThis file is part of the libiberty library.Libiberty is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General PublicLicense as published by the Free Software Foundation; eitherversion 2 of the License, or (at your option) any later version.Libiberty is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with libiberty; see the file COPYING.LIB.  Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA.  */#include "config.h"#include <stdio.h>#include <signal.h>/*  Routines imported from standard C runtime libraries. */#ifdef __STDC__#include <stddef.h>extern void *malloc (size_t size);				/* 4.10.3.3 */extern void *memset (void *s, int c, size_t n);			/* 4.11.6.1 */#else	/* !__STDC__ */extern char *malloc ();		/* Standard memory allocater */extern char *memset ();#endif	/* __STDC__ */#ifndef NULL#  ifdef __STDC__#    define NULL (void *) 0#  else#    define NULL 0#  endif#endif#ifndef MAX#  define MAX(a,b) ((a) > (b) ? (a) : (b))#endif/* Translation table for signal values.   Note that this table is generally only accessed when it is used at runtime   to initialize signal name and message tables that are indexed by signal   value.   Not all of these signals will exist on all systems.  This table is the only   thing that should have to be updated as new signal numbers are introduced.   It's sort of ugly, but at least its portable. */static struct signal_info{  int value;		/* The numeric value from <signal.h> */  char *name;		/* The equivalent symbolic value */  char *msg;		/* Short message about this value */} signal_table[] ={#if defined (SIGHUP)  SIGHUP, "SIGHUP", "Hangup",#endif#if defined (SIGINT)  SIGINT, "SIGINT", "Interrupt",#endif#if defined (SIGQUIT)  SIGQUIT, "SIGQUIT", "Quit",#endif#if defined (SIGILL)  SIGILL, "SIGILL", "Illegal instruction",#endif#if defined (SIGTRAP)  SIGTRAP, "SIGTRAP", "Trace/breakpoint trap",#endif/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT   overrides SIGIOT.  SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */#if defined (SIGIOT)  SIGIOT, "SIGIOT", "IOT trap",#endif#if defined (SIGABRT)  SIGABRT, "SIGABRT", "Aborted",#endif#if defined (SIGEMT)  SIGEMT, "SIGEMT", "Emulation trap",#endif#if defined (SIGFPE)  SIGFPE, "SIGFPE", "Arithmetic exception",#endif#if defined (SIGKILL)  SIGKILL, "SIGKILL", "Killed",#endif#if defined (SIGBUS)  SIGBUS, "SIGBUS", "Bus error",#endif#if defined (SIGSEGV)  SIGSEGV, "SIGSEGV", "Segmentation fault",#endif#if defined (SIGSYS)  SIGSYS, "SIGSYS", "Bad system call",#endif#if defined (SIGPIPE)  SIGPIPE, "SIGPIPE", "Broken pipe",#endif#if defined (SIGALRM)  SIGALRM, "SIGALRM", "Alarm clock",#endif#if defined (SIGTERM)  SIGTERM, "SIGTERM", "Terminated",#endif#if defined (SIGUSR1)  SIGUSR1, "SIGUSR1", "User defined signal 1",#endif#if defined (SIGUSR2)  SIGUSR2, "SIGUSR2", "User defined signal 2",#endif/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD   overrides SIGCLD.  SIGCHLD is in POXIX.1 */#if defined (SIGCLD)  SIGCLD, "SIGCLD", "Child status changed",#endif#if defined (SIGCHLD)  SIGCHLD, "SIGCHLD", "Child status changed",#endif#if defined (SIGPWR)  SIGPWR, "SIGPWR", "Power fail/restart",#endif#if defined (SIGWINCH)  SIGWINCH, "SIGWINCH", "Window size changed",#endif#if defined (SIGURG)  SIGURG, "SIGURG", "Urgent I/O condition",#endif#if defined (SIGIO)  /* "I/O pending has also been suggested, but is misleading since the     signal only happens when the process has asked for it, not everytime     I/O is pending. */  SIGIO, "SIGIO", "I/O possible",#endif#if defined (SIGPOLL)  SIGPOLL, "SIGPOLL", "Pollable event occurred",#endif#if defined (SIGSTOP)  SIGSTOP, "SIGSTOP", "Stopped (signal)",#endif#if defined (SIGTSTP)  SIGTSTP, "SIGTSTP", "Stopped (user)",#endif#if defined (SIGCONT)  SIGCONT, "SIGCONT", "Continued",#endif#if defined (SIGTTIN)  SIGTTIN, "SIGTTIN", "Stopped (tty input)",#endif#if defined (SIGTTOU)  SIGTTOU, "SIGTTOU", "Stopped (tty output)",#endif#if defined (SIGVTALRM)  SIGVTALRM, "SIGVTALRM", "Virtual timer expired",#endif#if defined (SIGPROF)  SIGPROF, "SIGPROF", "Profiling timer expired",#endif#if defined (SIGXCPU)  SIGXCPU, "SIGXCPU", "CPU time limit exceeded",#endif#if defined (SIGXFSZ)  SIGXFSZ, "SIGXFSZ", "File size limit exceeded",#endif#if defined (SIGWIND)  SIGWIND, "SIGWIND", "SIGWIND",#endif#if defined (SIGPHONE)  SIGPHONE, "SIGPHONE", "SIGPHONE",#endif#if defined (SIGLOST)  SIGLOST, "SIGLOST", "Resource lost",#endif#if defined (SIGWAITING)  SIGWAITING, "SIGWAITING", "Process's LWPs are blocked",#endif#if defined (SIGLWP)  SIGLWP, "SIGLWP", "Signal LWP",#endif  0, NULL, NULL};/* Translation table allocated and initialized at runtime.  Indexed by the   signal value to find the equivalent symbolic value. */static char **signal_names;static int num_signal_names = 0;/* Translation table allocated and initialized at runtime, if it does not   already exist in the host environment.  Indexed by the signal value to find   the descriptive string.   We don't export it for use in other modules because even though it has the   same name, it differs from other implementations in that it is dynamically   initialized rather than statically initialized. */#ifdef NEED_sys_sigliststatic int sys_nsig;#ifdef notdefstatic char **sys_siglist;#endif#elsestatic int sys_nsig = NSIG;#ifdef notdef#ifdef __STDC__extern char * const sys_siglist[];#elseextern char *sys_siglist[];#endif#endif#endif/*NAME	init_signal_tables -- initialize the name and message tablesSYNOPSIS	static void init_signal_tables ();DESCRIPTION	Using the signal_table, which is initialized at compile time, generate	the signal_names and the sys_siglist (if needed) tables, which are	indexed at runtime by a specific signal value.BUGS	The initialization of the tables may fail under low memory conditions,	in which case we don't do anything particularly useful, but we don't	bomb either.  Who knows, it might succeed at a later point if we free	some memory in the meantime.  In any case, the other routines know	how to deal with lack of a table after trying to initialize it.  This	may or may not be considered to be a bug, that we don't specifically	warn about this particular failure mode.*/static voidinit_signal_tables (){  struct signal_info *eip;  int nbytes;  /* If we haven't already scanned the signal_table once to find the maximum     signal value, then go find it now. */  if (num_signal_names == 0)    {      for (eip = signal_table; eip -> name != NULL; eip++)	{	  if (eip -> value >= num_signal_names)	    {	      num_signal_names = eip -> value + 1;	    }	}    }  /* Now attempt to allocate the signal_names table, zero it out, and then     initialize it from the statically initialized signal_table. */  if (signal_names == NULL)    {      nbytes = num_signal_names * sizeof (char *);      if ((signal_names = (char **) malloc (nbytes)) != NULL)	{	  memset (signal_names, 0, nbytes);	  for (eip = signal_table; eip -> name != NULL; eip++)	    {	      signal_names[eip -> value] = eip -> name;	    }	}    }#ifdef NEED_sys_siglist  /* Now attempt to allocate the sys_siglist table, zero it out, and then     initialize it from the statically initialized signal_table. */  if (sys_siglist == NULL)    {      nbytes = num_signal_names * sizeof (char *);      if ((sys_siglist = (char **) malloc (nbytes)) != NULL)	{	  memset (sys_siglist, 0, nbytes);	  sys_nsig = num_signal_names;	  for (eip = signal_table; eip -> name != NULL; eip++)	    {	      sys_siglist[eip -> value] = eip -> msg;	    }	}    }#endif}/*NAME	signo_max -- return the max signo valueSYNOPSIS	int signo_max ();DESCRIPTION	Returns the maximum signo value for which a corresponding symbolic	name or message is available.  Note that in the case where	we use the sys_siglist supplied by the system, it is possible for	there to be more symbolic names than messages, or vice versa.	In fact, the manual page for psignal(3b) explicitly warns that one	should check the size of the table (NSIG) before indexing it,	since new signal codes may be added to the system before they are	added to the table.  Thus NSIG might be smaller than value	implied by the largest signo value defined in <signal.h>.	We return the maximum value that can be used to obtain a meaningful	symbolic name or message.*/intsigno_max (){  int maxsize;  if (signal_names == NULL)    {      init_signal_tables ();    }  maxsize = MAX (sys_nsig, num_signal_names);  return (maxsize - 1);}/*NAME	strsignal -- map a signal number to a signal message stringSYNOPSIS	char *strsignal (int signo)DESCRIPTION	Maps an signal number to an signal message string, the contents of	which are implementation defined.  On systems which have the external	variable sys_siglist, these strings will be the same as the ones used	by psignal().	If the supplied signal number is within the valid range of indices	for the sys_siglist, but no message is available for the particular	signal number, then returns the string "Signal NUM", where NUM is the	signal number.	If the supplied signal number is not a valid index into sys_siglist,	returns NULL.	The returned string is only guaranteed to be valid only until the	next call to strsignal.*/char *strsignal (signo)  int signo;{  char *msg;  static char buf[32];#ifdef NEED_sys_siglist  if (signal_names == NULL)    {      init_signal_tables ();    }#endif  if ((signo < 0) || (signo >= sys_nsig))    {      /* Out of range, just return NULL */      msg = NULL;    }  else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))    {      /* In range, but no sys_siglist or no entry at this index. */      sprintf (buf, "Signal %d", signo);      msg = buf;    }  else    {      /* In range, and a valid message.  Just return the message. */      msg = (char*)sys_siglist[signo];    }    return (msg);}/*NAME	strsigno -- map an signal number to a symbolic name stringSYNOPSIS	char *strsigno (int signo)DESCRIPTION	Given an signal number, returns a pointer to a string containing	the symbolic name of that signal number, as found in <signal.h>.	If the supplied signal number is within the valid range of indices	for symbolic names, but no name is available for the particular	signal number, then returns the string "Signal NUM", where NUM is	the signal number.	If the supplied signal number is not within the range of valid	indices, then returns NULL.BUGS	The contents of the location pointed to are only guaranteed to be	valid until the next call to strsigno.*/char *strsigno (signo)  int signo;{  char *name;  static char buf[32];  if (signal_names == NULL)    {      init_signal_tables ();    }  if ((signo < 0) || (signo >= num_signal_names))    {      /* Out of range, just return NULL */      name = NULL;    }  else if ((signal_names == NULL) || (signal_names[signo] == NULL))    {      /* In range, but no signal_names or no entry at this index. */      sprintf (buf, "Signal %d", signo);      name = buf;    }  else    {      /* In range, and a valid name.  Just return the name. */      name = signal_names[signo];    }  return (name);}/*NAME	strtosigno -- map a symbolic signal name to a numeric valueSYNOPSIS	int strtosigno (char *name)DESCRIPTION	Given the symbolic name of a signal, map it to a signal number.	If no translation is found, returns 0.*/intstrtosigno (name)  char *name;{  int signo = 0;  if (name != NULL)    {      if (signal_names == NULL)	{	  init_signal_tables ();	}      for (signo = 0; signo < num_signal_names; signo++)	{	  if ((signal_names[signo] != NULL) &&	      (strcmp (name, signal_names[signo]) == 0))	    {	      break;	    }	}      if (signo == num_signal_names)	{	  signo = 0;	}    }  return (signo);}/*NAME	psignal -- print message about signal to stderrSYNOPSIS	void psignal (unsigned signo, char *message);DESCRIPTION	Print to the standard error the message, followed by a colon,	followed by the description of the signal specified by signo,	followed by a newline.*/#ifdef NEED_psignalvoidpsignal (signo, message)  unsigned signo;  char *message;{  if (signal_names == NULL)    {      init_signal_tables ();    }  if ((signo <= 0) || (signo >= sys_nsig))    {      fprintf (stderr, "%s: unknown signal\n", message);    }  else    {      fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);    }}#endif	/* NEED_psignal *//* A simple little main that does nothing but print all the signal translations   if MAIN is defined and this file is compiled and linked. */#ifdef MAINmain (){  int signo;  int maxsigno;  char *name;  char *msg;  char *strsigno ();  char *strsignal ();  maxsigno = signo_max ();  printf ("%d entries in names table.\n", num_signal_names);  printf ("%d entries in messages table.\n", sys_nsig);  printf ("%d is max useful index.\n", maxsigno);  /* Keep printing values until we get to the end of *both* tables, not     *either* table.  Note that knowing the maximum useful index does *not*     relieve us of the responsibility of testing the return pointer for     NULL. */  for (signo = 0; signo <= maxsigno; signo++)    {      name = strsigno (signo);      name = (name == NULL) ? "<NULL>" : name;      msg = strsignal (signo);      msg = (msg == NULL) ? "<NULL>" : msg;      printf ("%-4d%-18s%s\n", signo, name, msg);    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -