Annotation of GNUtools/debug/gdb/libiberty/strsignal.c, revision 1.1.1.1

1.1       root        1: /* Extended support for using signal values.
                      2:    Copyright (C) 1992 Free Software Foundation, Inc.
                      3:    Written by Fred Fish.  [email protected]
                      4: 
                      5: This file is part of the libiberty library.
                      6: Libiberty is free software; you can redistribute it and/or
                      7: modify it under the terms of the GNU Library General Public
                      8: License as published by the Free Software Foundation; either
                      9: version 2 of the License, or (at your option) any later version.
                     10: 
                     11: Libiberty is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14: Library General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU Library General Public
                     17: License along with libiberty; see the file COPYING.LIB.  If
                     18: not, write to the Free Software Foundation, Inc., 675 Mass Ave,
                     19: Cambridge, MA 02139, USA.  */
                     20: 
                     21: //#include "config.h"
                     22: 
                     23: #include <stdio.h>
                     24: #include <signal.h>
                     25: 
                     26: /*  Routines imported from standard C runtime libraries. */
                     27: 
                     28: #ifdef __STDC__
                     29: #include <stddef.h>
                     30: extern void *malloc (size_t size);                             /* 4.10.3.3 */
                     31: extern void *memset (void *s, int c, size_t n);                        /* 4.11.6.1 */
                     32: #else  /* !__STDC__ */
                     33: extern char *malloc ();                /* Standard memory allocater */
                     34: extern char *memset ();
                     35: #endif /* __STDC__ */
                     36: 
                     37: #ifndef NULL
                     38: #  ifdef __STDC__
                     39: #    define NULL (void *) 0
                     40: #  else
                     41: #    define NULL 0
                     42: #  endif
                     43: #endif
                     44: 
                     45: #ifndef MAX
                     46: #  define MAX(a,b) ((a) > (b) ? (a) : (b))
                     47: #endif
                     48: 
                     49: /* Translation table for signal values.
                     50: 
                     51:    Note that this table is generally only accessed when it is used at runtime
                     52:    to initialize signal name and message tables that are indexed by signal
                     53:    value.
                     54: 
                     55:    Not all of these signals will exist on all systems.  This table is the only
                     56:    thing that should have to be updated as new signal numbers are introduced.
                     57:    It's sort of ugly, but at least its portable. */
                     58: 
                     59: static struct signal_info
                     60: {
                     61:   int value;           /* The numeric value from <signal.h> */
                     62:   char *name;          /* The equivalent symbolic value */
                     63:   char *msg;           /* Short message about this value */
                     64: } signal_table[] =
                     65: {
                     66: #if defined (SIGHUP)
                     67:   SIGHUP, "SIGHUP", "Hangup",
                     68: #endif
                     69: #if defined (SIGINT)
                     70:   SIGINT, "SIGINT", "Interrupt",
                     71: #endif
                     72: #if defined (SIGQUIT)
                     73:   SIGQUIT, "SIGQUIT", "Quit",
                     74: #endif
                     75: #if defined (SIGILL)
                     76:   SIGILL, "SIGILL", "Illegal instruction",
                     77: #endif
                     78: #if defined (SIGTRAP)
                     79:   SIGTRAP, "SIGTRAP", "Trace/breakpoint trap",
                     80: #endif
                     81: /* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
                     82:    overrides SIGIOT.  SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
                     83: #if defined (SIGIOT)
                     84:   SIGIOT, "SIGIOT", "IOT trap",
                     85: #endif
                     86: #if defined (SIGABRT)
                     87:   SIGABRT, "SIGABRT", "Aborted",
                     88: #endif
                     89: #if defined (SIGEMT)
                     90:   SIGEMT, "SIGEMT", "Emulation trap",
                     91: #endif
                     92: #if defined (SIGFPE)
                     93:   SIGFPE, "SIGFPE", "Arithmetic exception",
                     94: #endif
                     95: #if defined (SIGKILL)
                     96:   SIGKILL, "SIGKILL", "Killed",
                     97: #endif
                     98: #if defined (SIGBUS)
                     99:   SIGBUS, "SIGBUS", "Bus error",
                    100: #endif
                    101: #if defined (SIGSEGV)
                    102:   SIGSEGV, "SIGSEGV", "Segmentation fault",
                    103: #endif
                    104: #if defined (SIGSYS)
                    105:   SIGSYS, "SIGSYS", "Bad system call",
                    106: #endif
                    107: #if defined (SIGPIPE)
                    108:   SIGPIPE, "SIGPIPE", "Broken pipe",
                    109: #endif
                    110: #if defined (SIGALRM)
                    111:   SIGALRM, "SIGALRM", "Alarm clock",
                    112: #endif
                    113: #if defined (SIGTERM)
                    114:   SIGTERM, "SIGTERM", "Terminated",
                    115: #endif
                    116: #if defined (SIGUSR1)
                    117:   SIGUSR1, "SIGUSR1", "User defined signal 1",
                    118: #endif
                    119: #if defined (SIGUSR2)
                    120:   SIGUSR2, "SIGUSR2", "User defined signal 2",
                    121: #endif
                    122: /* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
                    123:    overrides SIGCLD.  SIGCHLD is in POXIX.1 */
                    124: #if defined (SIGCLD)
                    125:   SIGCLD, "SIGCLD", "Child status changed",
                    126: #endif
                    127: #if defined (SIGCHLD)
                    128:   SIGCHLD, "SIGCHLD", "Child status changed",
                    129: #endif
                    130: #if defined (SIGPWR)
                    131:   SIGPWR, "SIGPWR", "Power fail/restart",
                    132: #endif
                    133: #if defined (SIGWINCH)
                    134:   SIGWINCH, "SIGWINCH", "Window size changed",
                    135: #endif
                    136: #if defined (SIGURG)
                    137:   SIGURG, "SIGURG", "Urgent I/O condition",
                    138: #endif
                    139: #if defined (SIGIO)
                    140:   /* "I/O pending has also been suggested, but is misleading since the
                    141:      signal only happens when the process has asked for it, not everytime
                    142:      I/O is pending. */
                    143:   SIGIO, "SIGIO", "I/O possible",
                    144: #endif
                    145: #if defined (SIGPOLL)
                    146:   SIGPOLL, "SIGPOLL", "Pollable event occurred",
                    147: #endif
                    148: #if defined (SIGSTOP)
                    149:   SIGSTOP, "SIGSTOP", "Stopped (signal)",
                    150: #endif
                    151: #if defined (SIGTSTP)
                    152:   SIGTSTP, "SIGTSTP", "Stopped (user)",
                    153: #endif
                    154: #if defined (SIGCONT)
                    155:   SIGCONT, "SIGCONT", "Continued",
                    156: #endif
                    157: #if defined (SIGTTIN)
                    158:   SIGTTIN, "SIGTTIN", "Stopped (tty input)",
                    159: #endif
                    160: #if defined (SIGTTOU)
                    161:   SIGTTOU, "SIGTTOU", "Stopped (tty output)",
                    162: #endif
                    163: #if defined (SIGVTALRM)
                    164:   SIGVTALRM, "SIGVTALRM", "Virtual timer expired",
                    165: #endif
                    166: #if defined (SIGPROF)
                    167:   SIGPROF, "SIGPROF", "Profiling timer expired",
                    168: #endif
                    169: #if defined (SIGXCPU)
                    170:   SIGXCPU, "SIGXCPU", "CPU time limit exceeded",
                    171: #endif
                    172: #if defined (SIGXFSZ)
                    173:   SIGXFSZ, "SIGXFSZ", "File size limit exceeded",
                    174: #endif
                    175: #if defined (SIGWIND)
                    176:   SIGWIND, "SIGWIND", "SIGWIND",
                    177: #endif
                    178: #if defined (SIGPHONE)
                    179:   SIGPHONE, "SIGPHONE", "SIGPHONE",
                    180: #endif
                    181: #if defined (SIGLOST)
                    182:   SIGLOST, "SIGLOST", "Resource lost",
                    183: #endif
                    184: #if defined (SIGWAITING)
                    185:   SIGWAITING, "SIGWAITING", "Process's LWPs are blocked",
                    186: #endif
                    187: #if defined (SIGLWP)
                    188:   SIGLWP, "SIGLWP", "Signal LWP",
                    189: #endif
                    190:   0, NULL, NULL
                    191: };
                    192: 
                    193: /* Translation table allocated and initialized at runtime.  Indexed by the
                    194:    signal value to find the equivalent symbolic value. */
                    195: 
                    196: static char **signal_names;
                    197: static int num_signal_names = 0;
                    198: 
                    199: /* Translation table allocated and initialized at runtime, if it does not
                    200:    already exist in the host environment.  Indexed by the signal value to find
                    201:    the descriptive string.
                    202: 
                    203:    We don't export it for use in other modules because even though it has the
                    204:    same name, it differs from other implementations in that it is dynamically
                    205:    initialized rather than statically initialized. */
                    206: 
                    207: #ifdef NEED_sys_siglist
                    208: 
                    209: static int sys_nsig;
                    210: static char **sys_siglist;
                    211: 
                    212: #else
                    213: 
                    214: static int sys_nsig = NSIG;
                    215: #ifdef __STDC__
                    216: extern const char * const sys_siglist[];
                    217: #else
                    218: extern char *sys_siglist[];
                    219: #endif
                    220: #endif
                    221: 
                    222: 
                    223: /*
                    224: 
                    225: NAME
                    226: 
                    227:        init_signal_tables -- initialize the name and message tables
                    228: 
                    229: SYNOPSIS
                    230: 
                    231:        static void init_signal_tables ();
                    232: 
                    233: DESCRIPTION
                    234: 
                    235:        Using the signal_table, which is initialized at compile time, generate
                    236:        the signal_names and the sys_siglist (if needed) tables, which are
                    237:        indexed at runtime by a specific signal value.
                    238: 
                    239: BUGS
                    240: 
                    241:        The initialization of the tables may fail under low memory conditions,
                    242:        in which case we don't do anything particularly useful, but we don't
                    243:        bomb either.  Who knows, it might succeed at a later point if we free
                    244:        some memory in the meantime.  In any case, the other routines know
                    245:        how to deal with lack of a table after trying to initialize it.  This
                    246:        may or may not be considered to be a bug, that we don't specifically
                    247:        warn about this particular failure mode.
                    248: 
                    249: */
                    250: 
                    251: static void
                    252: init_signal_tables ()
                    253: {
                    254:   struct signal_info *eip;
                    255:   int nbytes;
                    256: 
                    257:   /* If we haven't already scanned the signal_table once to find the maximum
                    258:      signal value, then go find it now. */
                    259: 
                    260:   if (num_signal_names == 0)
                    261:     {
                    262:       for (eip = signal_table; eip -> name != NULL; eip++)
                    263:        {
                    264:          if (eip -> value >= num_signal_names)
                    265:            {
                    266:              num_signal_names = eip -> value + 1;
                    267:            }
                    268:        }
                    269:     }
                    270: 
                    271:   /* Now attempt to allocate the signal_names table, zero it out, and then
                    272:      initialize it from the statically initialized signal_table. */
                    273: 
                    274:   if (signal_names == NULL)
                    275:     {
                    276:       nbytes = num_signal_names * sizeof (char *);
                    277:       if ((signal_names = (char **) malloc (nbytes)) != NULL)
                    278:        {
                    279:          memset (signal_names, 0, nbytes);
                    280:          for (eip = signal_table; eip -> name != NULL; eip++)
                    281:            {
                    282:              signal_names[eip -> value] = eip -> name;
                    283:            }
                    284:        }
                    285:     }
                    286: 
                    287: #ifdef NEED_sys_siglist
                    288: 
                    289:   /* Now attempt to allocate the sys_siglist table, zero it out, and then
                    290:      initialize it from the statically initialized signal_table. */
                    291: 
                    292:   if (sys_siglist == NULL)
                    293:     {
                    294:       nbytes = num_signal_names * sizeof (char *);
                    295:       if ((sys_siglist = (char **) malloc (nbytes)) != NULL)
                    296:        {
                    297:          memset (sys_siglist, 0, nbytes);
                    298:          sys_nsig = num_signal_names;
                    299:          for (eip = signal_table; eip -> name != NULL; eip++)
                    300:            {
                    301:              sys_siglist[eip -> value] = eip -> msg;
                    302:            }
                    303:        }
                    304:     }
                    305: 
                    306: #endif
                    307: 
                    308: }
                    309: 
                    310: 
                    311: /*
                    312: 
                    313: NAME
                    314: 
                    315:        signo_max -- return the max signo value
                    316: 
                    317: SYNOPSIS
                    318: 
                    319:        int signo_max ();
                    320: 
                    321: DESCRIPTION
                    322: 
                    323:        Returns the maximum signo value for which a corresponding symbolic
                    324:        name or message is available.  Note that in the case where
                    325:        we use the sys_siglist supplied by the system, it is possible for
                    326:        there to be more symbolic names than messages, or vice versa.
                    327:        In fact, the manual page for psignal(3b) explicitly warns that one
                    328:        should check the size of the table (NSIG) before indexing it,
                    329:        since new signal codes may be added to the system before they are
                    330:        added to the table.  Thus NSIG might be smaller than value
                    331:        implied by the largest signo value defined in <signal.h>.
                    332: 
                    333:        We return the maximum value that can be used to obtain a meaningful
                    334:        symbolic name or message.
                    335: 
                    336: */
                    337: 
                    338: int
                    339: signo_max ()
                    340: {
                    341:   int maxsize;
                    342: 
                    343:   if (signal_names == NULL)
                    344:     {
                    345:       init_signal_tables ();
                    346:     }
                    347:   maxsize = MAX (sys_nsig, num_signal_names);
                    348:   return (maxsize - 1);
                    349: }
                    350: 
                    351: 
                    352: /*
                    353: 
                    354: NAME
                    355: 
                    356:        strsignal -- map a signal number to a signal message string
                    357: 
                    358: SYNOPSIS
                    359: 
                    360:        char *strsignal (int signo)
                    361: 
                    362: DESCRIPTION
                    363: 
                    364:        Maps an signal number to an signal message string, the contents of
                    365:        which are implementation defined.  On systems which have the external
                    366:        variable sys_siglist, these strings will be the same as the ones used
                    367:        by psignal().
                    368: 
                    369:        If the supplied signal number is within the valid range of indices
                    370:        for the sys_siglist, but no message is available for the particular
                    371:        signal number, then returns the string "Signal NUM", where NUM is the
                    372:        signal number.
                    373: 
                    374:        If the supplied signal number is not a valid index into sys_siglist,
                    375:        returns NULL.
                    376: 
                    377:        The returned string is only guaranteed to be valid only until the
                    378:        next call to strsignal.
                    379: 
                    380: */
                    381: 
                    382: char *
                    383: strsignal (signo)
                    384:   int signo;
                    385: {
                    386:   char *msg;
                    387:   static char buf[32];
                    388: 
                    389: #ifdef NEED_sys_siglist
                    390: 
                    391:   if (signal_names == NULL)
                    392:     {
                    393:       init_signal_tables ();
                    394:     }
                    395: 
                    396: #endif
                    397: 
                    398:   if ((signo < 0) || (signo >= sys_nsig))
                    399:     {
                    400:       /* Out of range, just return NULL */
                    401:       msg = NULL;
                    402:     }
                    403:   else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
                    404:     {
                    405:       /* In range, but no sys_siglist or no entry at this index. */
                    406:       sprintf (buf, "Signal %d", signo);
                    407:       msg = buf;
                    408:     }
                    409:   else
                    410:     {
                    411:       /* In range, and a valid message.  Just return the message. */
                    412:       msg = (char*)sys_siglist[signo];
                    413:     }
                    414:   
                    415:   return (msg);
                    416: }
                    417: 
                    418: 
                    419: /*
                    420: 
                    421: NAME
                    422: 
                    423:        strsigno -- map an signal number to a symbolic name string
                    424: 
                    425: SYNOPSIS
                    426: 
                    427:        char *strsigno (int signo)
                    428: 
                    429: DESCRIPTION
                    430: 
                    431:        Given an signal number, returns a pointer to a string containing
                    432:        the symbolic name of that signal number, as found in <signal.h>.
                    433: 
                    434:        If the supplied signal number is within the valid range of indices
                    435:        for symbolic names, but no name is available for the particular
                    436:        signal number, then returns the string "Signal NUM", where NUM is
                    437:        the signal number.
                    438: 
                    439:        If the supplied signal number is not within the range of valid
                    440:        indices, then returns NULL.
                    441: 
                    442: BUGS
                    443: 
                    444:        The contents of the location pointed to are only guaranteed to be
                    445:        valid until the next call to strsigno.
                    446: 
                    447: */
                    448: 
                    449: char *
                    450: strsigno (signo)
                    451:   int signo;
                    452: {
                    453:   char *name;
                    454:   static char buf[32];
                    455: 
                    456:   if (signal_names == NULL)
                    457:     {
                    458:       init_signal_tables ();
                    459:     }
                    460: 
                    461:   if ((signo < 0) || (signo >= num_signal_names))
                    462:     {
                    463:       /* Out of range, just return NULL */
                    464:       name = NULL;
                    465:     }
                    466:   else if ((signal_names == NULL) || (signal_names[signo] == NULL))
                    467:     {
                    468:       /* In range, but no signal_names or no entry at this index. */
                    469:       sprintf (buf, "Signal %d", signo);
                    470:       name = buf;
                    471:     }
                    472:   else
                    473:     {
                    474:       /* In range, and a valid name.  Just return the name. */
                    475:       name = signal_names[signo];
                    476:     }
                    477: 
                    478:   return (name);
                    479: }
                    480: 
                    481: 
                    482: /*
                    483: 
                    484: NAME
                    485: 
                    486:        strtosigno -- map a symbolic signal name to a numeric value
                    487: 
                    488: SYNOPSIS
                    489: 
                    490:        int strtosigno (char *name)
                    491: 
                    492: DESCRIPTION
                    493: 
                    494:        Given the symbolic name of a signal, map it to a signal number.
                    495:        If no translation is found, returns 0.
                    496: 
                    497: */
                    498: 
                    499: int
                    500: strtosigno (name)
                    501:   char *name;
                    502: {
                    503:   int signo = 0;
                    504: 
                    505:   if (name != NULL)
                    506:     {
                    507:       if (signal_names == NULL)
                    508:        {
                    509:          init_signal_tables ();
                    510:        }
                    511:       for (signo = 0; signo < num_signal_names; signo++)
                    512:        {
                    513:          if ((signal_names[signo] != NULL) &&
                    514:              (strcmp (name, signal_names[signo]) == 0))
                    515:            {
                    516:              break;
                    517:            }
                    518:        }
                    519:       if (signo == num_signal_names)
                    520:        {
                    521:          signo = 0;
                    522:        }
                    523:     }
                    524:   return (signo);
                    525: }
                    526: 
                    527: 
                    528: /*
                    529: 
                    530: NAME
                    531: 
                    532:        psignal -- print message about signal to stderr
                    533: 
                    534: SYNOPSIS
                    535: 
                    536:        void psignal (unsigned signo, char *message);
                    537: 
                    538: DESCRIPTION
                    539: 
                    540:        Print to the standard error the message, followed by a colon,
                    541:        followed by the description of the signal specified by signo,
                    542:        followed by a newline.
                    543: */
                    544: 
                    545: #ifdef NEED_psignal
                    546: 
                    547: void
                    548: psignal (signo, message)
                    549:   unsigned signo;
                    550:   char *message;
                    551: {
                    552:   if (signal_names == NULL)
                    553:     {
                    554:       init_signal_tables ();
                    555:     }
                    556:   if ((signo <= 0) || (signo >= sys_nsig))
                    557:     {
                    558:       fprintf (stderr, "%s: unknown signal\n", message);
                    559:     }
                    560:   else
                    561:     {
                    562:       fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
                    563:     }
                    564: }
                    565: 
                    566: #endif /* NEED_psignal */
                    567: 
                    568: 
                    569: /* A simple little main that does nothing but print all the signal translations
                    570:    if MAIN is defined and this file is compiled and linked. */
                    571: 
                    572: #ifdef MAIN
                    573: 
                    574: main ()
                    575: {
                    576:   int signo;
                    577:   int maxsigno;
                    578:   char *name;
                    579:   char *msg;
                    580:   char *strsigno ();
                    581:   char *strsignal ();
                    582: 
                    583:   maxsigno = signo_max ();
                    584:   printf ("%d entries in names table.\n", num_signal_names);
                    585:   printf ("%d entries in messages table.\n", sys_nsig);
                    586:   printf ("%d is max useful index.\n", maxsigno);
                    587: 
                    588:   /* Keep printing values until we get to the end of *both* tables, not
                    589:      *either* table.  Note that knowing the maximum useful index does *not*
                    590:      relieve us of the responsibility of testing the return pointer for
                    591:      NULL. */
                    592: 
                    593:   for (signo = 0; signo <= maxsigno; signo++)
                    594:     {
                    595:       name = strsigno (signo);
                    596:       name = (name == NULL) ? "<NULL>" : name;
                    597:       msg = strsignal (signo);
                    598:       msg = (msg == NULL) ? "<NULL>" : msg;
                    599:       printf ("%-4d%-18s%s\n", signo, name, msg);
                    600:     }
                    601: }
                    602: 
                    603: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.