root/lib/sig2str.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. str2signum
  2. str2sig
  3. sig2str

     1 /* sig2str.c -- convert between signal names and numbers
     2 
     3    Copyright (C) 2002, 2004, 2006, 2009-2023 Free Software Foundation,
     4    Inc.
     5 
     6    This program is free software: you can redistribute it and/or modify
     7    it under the terms of the GNU General Public License as published by
     8    the Free Software Foundation, either version 3 of the License, or
     9    (at your option) any later version.
    10 
    11    This program 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
    14    GNU General Public License for more details.
    15 
    16    You should have received a copy of the GNU General Public License
    17    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
    18 
    19 /* Written by Paul Eggert.  */
    20 
    21 #include <config.h>
    22 
    23 #include <limits.h>
    24 #include <signal.h>
    25 #include <stdlib.h>
    26 #include <stdio.h>
    27 #include <string.h>
    28 
    29 #include "sig2str.h"
    30 
    31 #ifndef SIGRTMIN
    32 # define SIGRTMIN 0
    33 # undef SIGRTMAX
    34 #endif
    35 #ifndef SIGRTMAX
    36 # define SIGRTMAX (SIGRTMIN - 1)
    37 #endif
    38 
    39 #define NUMNAME(name) { SIG##name, #name }
    40 
    41 /* Signal names and numbers.  Put the preferred name first.  */
    42 static struct numname { int num; char const name[8]; } numname_table[] =
    43   {
    44     /* Signals required by POSIX 1003.1-2001 base, listed in
    45        traditional numeric order where possible.  */
    46 #ifdef SIGHUP
    47     NUMNAME (HUP),
    48 #endif
    49 #ifdef SIGINT
    50     NUMNAME (INT),
    51 #endif
    52 #ifdef SIGQUIT
    53     NUMNAME (QUIT),
    54 #endif
    55 #ifdef SIGILL
    56     NUMNAME (ILL),
    57 #endif
    58 #ifdef SIGTRAP
    59     NUMNAME (TRAP),
    60 #endif
    61 #ifdef SIGABRT
    62     NUMNAME (ABRT),
    63 #endif
    64 #ifdef SIGFPE
    65     NUMNAME (FPE),
    66 #endif
    67 #ifdef SIGKILL
    68     NUMNAME (KILL),
    69 #endif
    70 #ifdef SIGSEGV
    71     NUMNAME (SEGV),
    72 #endif
    73     /* On Haiku, SIGSEGV == SIGBUS, but we prefer SIGSEGV to match
    74        strsignal.c output, so SIGBUS must be listed second.  */
    75 #ifdef SIGBUS
    76     NUMNAME (BUS),
    77 #endif
    78 #ifdef SIGPIPE
    79     NUMNAME (PIPE),
    80 #endif
    81 #ifdef SIGALRM
    82     NUMNAME (ALRM),
    83 #endif
    84 #ifdef SIGTERM
    85     NUMNAME (TERM),
    86 #endif
    87 #ifdef SIGUSR1
    88     NUMNAME (USR1),
    89 #endif
    90 #ifdef SIGUSR2
    91     NUMNAME (USR2),
    92 #endif
    93 #ifdef SIGCHLD
    94     NUMNAME (CHLD),
    95 #endif
    96 #ifdef SIGURG
    97     NUMNAME (URG),
    98 #endif
    99 #ifdef SIGSTOP
   100     NUMNAME (STOP),
   101 #endif
   102 #ifdef SIGTSTP
   103     NUMNAME (TSTP),
   104 #endif
   105 #ifdef SIGCONT
   106     NUMNAME (CONT),
   107 #endif
   108 #ifdef SIGTTIN
   109     NUMNAME (TTIN),
   110 #endif
   111 #ifdef SIGTTOU
   112     NUMNAME (TTOU),
   113 #endif
   114 
   115     /* Signals required by POSIX 1003.1-2001 with the XSI extension.  */
   116 #ifdef SIGSYS
   117     NUMNAME (SYS),
   118 #endif
   119 #ifdef SIGPOLL
   120     NUMNAME (POLL),
   121 #endif
   122 #ifdef SIGVTALRM
   123     NUMNAME (VTALRM),
   124 #endif
   125 #ifdef SIGPROF
   126     NUMNAME (PROF),
   127 #endif
   128 #ifdef SIGXCPU
   129     NUMNAME (XCPU),
   130 #endif
   131 #ifdef SIGXFSZ
   132     NUMNAME (XFSZ),
   133 #endif
   134 
   135     /* Unix Version 7.  */
   136 #ifdef SIGIOT
   137     NUMNAME (IOT),      /* Older name for ABRT.  */
   138 #endif
   139 #ifdef SIGEMT
   140     NUMNAME (EMT),
   141 #endif
   142 
   143     /* USG Unix.  */
   144 #ifdef SIGPHONE
   145     NUMNAME (PHONE),
   146 #endif
   147 #ifdef SIGWIND
   148     NUMNAME (WIND),
   149 #endif
   150 
   151     /* Unix System V.  */
   152 #ifdef SIGCLD
   153     NUMNAME (CLD),
   154 #endif
   155 #ifdef SIGPWR
   156     NUMNAME (PWR),
   157 #endif
   158 
   159     /* GNU/Linux 2.2 and Solaris 8.  */
   160 #ifdef SIGCANCEL
   161     NUMNAME (CANCEL),
   162 #endif
   163 #ifdef SIGLWP
   164     NUMNAME (LWP),
   165 #endif
   166 #ifdef SIGWAITING
   167     NUMNAME (WAITING),
   168 #endif
   169 #ifdef SIGFREEZE
   170     NUMNAME (FREEZE),
   171 #endif
   172 #ifdef SIGTHAW
   173     NUMNAME (THAW),
   174 #endif
   175 #ifdef SIGLOST
   176     NUMNAME (LOST),
   177 #endif
   178 #ifdef SIGWINCH
   179     NUMNAME (WINCH),
   180 #endif
   181 
   182     /* GNU/Linux 2.2.  */
   183 #ifdef SIGINFO
   184     NUMNAME (INFO),
   185 #endif
   186 #ifdef SIGIO
   187     NUMNAME (IO),
   188 #endif
   189 #ifdef SIGSTKFLT
   190     NUMNAME (STKFLT),
   191 #endif
   192 
   193     /* AIX 7.  */
   194 #ifdef SIGCPUFAIL
   195     NUMNAME (CPUFAIL),
   196 #endif
   197 
   198     /* AIX 5L.  */
   199 #ifdef SIGDANGER
   200     NUMNAME (DANGER),
   201 #endif
   202 #ifdef SIGGRANT
   203     NUMNAME (GRANT),
   204 #endif
   205 #ifdef SIGMIGRATE
   206     NUMNAME (MIGRATE),
   207 #endif
   208 #ifdef SIGMSG
   209     NUMNAME (MSG),
   210 #endif
   211 #ifdef SIGPRE
   212     NUMNAME (PRE),
   213 #endif
   214 #ifdef SIGRETRACT
   215     NUMNAME (RETRACT),
   216 #endif
   217 #ifdef SIGSAK
   218     NUMNAME (SAK),
   219 #endif
   220 #ifdef SIGSOUND
   221     NUMNAME (SOUND),
   222 #endif
   223 
   224     /* Older AIX versions.  */
   225 #ifdef SIGALRM1
   226     NUMNAME (ALRM1),    /* unknown; taken from Bash 2.05 */
   227 #endif
   228 #ifdef SIGKAP
   229     NUMNAME (KAP),      /* Older name for SIGGRANT.  */
   230 #endif
   231 #ifdef SIGVIRT
   232     NUMNAME (VIRT),     /* unknown; taken from Bash 2.05 */
   233 #endif
   234 #ifdef SIGWINDOW
   235     NUMNAME (WINDOW),   /* Older name for SIGWINCH.  */
   236 #endif
   237 
   238     /* OpenBSD.  */
   239 #ifdef SIGTHR
   240     NUMNAME (THR),
   241 #endif
   242 
   243     /* BeOS, Haiku */
   244 #ifdef SIGKILLTHR
   245     NUMNAME (KILLTHR),
   246 #endif
   247 
   248     /* Older HP-UX versions.  */
   249 #ifdef SIGDIL
   250     NUMNAME (DIL),
   251 #endif
   252 
   253     /* native Windows */
   254 #ifdef SIGBREAK
   255     NUMNAME (BREAK),
   256 #endif
   257 
   258     /* Korn shell and Bash, of uncertain vintage.  */
   259     { 0, "EXIT" }
   260   };
   261 
   262 #define NUMNAME_ENTRIES (sizeof numname_table / sizeof numname_table[0])
   263 
   264 /* ISDIGIT differs from isdigit, as follows:
   265    - Its arg may be any int or unsigned int; it need not be an unsigned char
   266      or EOF.
   267    - It's typically faster.
   268    POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to
   269    isdigit unless it's important to use the locale's definition
   270    of "digit" even when the host does not conform to POSIX.  */
   271 #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
   272 
   273 /* Convert the signal name SIGNAME to a signal number.  Return the
   274    signal number if successful, -1 otherwise.  */
   275 
   276 static int
   277 str2signum (char const *signame)
   278 {
   279   if (ISDIGIT (*signame))
   280     {
   281       char *endp;
   282       long int n = strtol (signame, &endp, 10);
   283       if (! *endp && n <= SIGNUM_BOUND)
   284         return n;
   285     }
   286   else
   287     {
   288       unsigned int i;
   289       for (i = 0; i < NUMNAME_ENTRIES; i++)
   290         if (strcmp (numname_table[i].name, signame) == 0)
   291           return numname_table[i].num;
   292 
   293       {
   294         char *endp;
   295         int rtmin = SIGRTMIN;
   296         int rtmax = SIGRTMAX;
   297 
   298         if (0 < rtmin && strncmp (signame, "RTMIN", 5) == 0)
   299           {
   300             long int n = strtol (signame + 5, &endp, 10);
   301             if (! *endp && 0 <= n && n <= rtmax - rtmin)
   302               return rtmin + n;
   303           }
   304         else if (0 < rtmax && strncmp (signame, "RTMAX", 5) == 0)
   305           {
   306             long int n = strtol (signame + 5, &endp, 10);
   307             if (! *endp && rtmin - rtmax <= n && n <= 0)
   308               return rtmax + n;
   309           }
   310       }
   311     }
   312 
   313   return -1;
   314 }
   315 
   316 /* Convert the signal name SIGNAME to the signal number *SIGNUM.
   317    Return 0 if successful, -1 otherwise.  */
   318 
   319 int
   320 str2sig (char const *signame, int *signum)
   321 {
   322   *signum = str2signum (signame);
   323   return *signum < 0 ? -1 : 0;
   324 }
   325 
   326 /* Convert SIGNUM to a signal name in SIGNAME.  SIGNAME must point to
   327    a buffer of at least SIG2STR_MAX bytes.  Return 0 if successful, -1
   328    otherwise.  */
   329 
   330 int
   331 sig2str (int signum, char *signame)
   332 {
   333   unsigned int i;
   334   for (i = 0; i < NUMNAME_ENTRIES; i++)
   335     if (numname_table[i].num == signum)
   336       {
   337         strcpy (signame, numname_table[i].name);
   338         return 0;
   339       }
   340 
   341   {
   342     int rtmin = SIGRTMIN;
   343     int rtmax = SIGRTMAX;
   344     int base, delta;
   345 
   346     if (! (rtmin <= signum && signum <= rtmax))
   347       return -1;
   348 
   349     if (signum <= rtmin + (rtmax - rtmin) / 2)
   350       {
   351         strcpy (signame, "RTMIN");
   352         base = rtmin;
   353       }
   354     else
   355       {
   356         strcpy (signame, "RTMAX");
   357         base = rtmax;
   358       }
   359 
   360     delta = signum - base;
   361     if (delta != 0)
   362       sprintf (signame + 5, "%+d", delta);
   363     return 0;
   364   }
   365 }

/* [<][>][^][v][top][bottom][index][help] */