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

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