Annotation of GNUtools/debug/gdb/libiberty/strsignal.c, revision 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.