Coverage Report

Created: 2025-10-10 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sudo/lib/util/str2sig.c
Line
Count
Source
1
/*
2
 * SPDX-License-Identifier: ISC
3
 *
4
 * Copyright (c) 2019-2020 Todd C. Miller <Todd.Miller@sudo.ws>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <config.h>
20
21
#ifndef HAVE_STR2SIG
22
23
#include <errno.h>
24
#include <string.h>
25
#ifdef HAVE_STRINGS_H
26
# include <strings.h>
27
#endif /* HAVE_STRINGS_H */
28
#include <ctype.h>
29
#include <signal.h>
30
#include <unistd.h>
31
32
#include <sudo_compat.h>
33
#include <sudo_util.h>
34
35
#if !defined(HAVE_SIGABBREV_NP)
36
# if defined(HAVE_DECL_SYS_SIGNAME) && HAVE_DECL_SYS_SIGNAME == 1
37
#   define sigabbrev_np(_x) sys_signame[(_x)]
38
# elif defined(HAVE_DECL__SYS_SIGNAME) && HAVE_DECL__SYS_SIGNAME == 1
39
#   define sigabbrev_np(_x) _sys_signame[(_x)]
40
# elif defined(HAVE_SYS_SIGABBREV)
41
0
#   define sigabbrev_np(_x) sys_sigabbrev[(_x)]
42
#  if defined(HAVE_DECL_SYS_SIGABBREV) && HAVE_DECL_SYS_SIGABBREV == 0
43
    /* sys_sigabbrev is not declared by glibc */
44
    extern const char *const sys_sigabbrev[NSIG];
45
#  endif
46
# else
47
#   define sigabbrev_np(_x) sudo_sys_signame[(_x)]
48
    extern const char *const sudo_sys_signame[NSIG];
49
# endif
50
#endif /* !HAVE_SIGABBREV_NP */
51
52
/*
53
 * Many systems use aliases for source backward compatibility.
54
 */
55
static struct sigalias {
56
    const char *name;
57
    int number;
58
} sigaliases[] = {
59
#ifdef SIGABRT
60
    { "ABRT", SIGABRT },
61
#endif
62
#ifdef SIGCLD
63
    { "CLD",  SIGCLD },
64
#endif
65
#ifdef SIGIO
66
    { "IO",   SIGIO },
67
#endif
68
#ifdef SIGIOT
69
    { "IOT",  SIGIOT },
70
#endif
71
#ifdef SIGLOST
72
    { "LOST", SIGLOST },
73
#endif
74
#ifdef SIGPOLL
75
    { "POLL", SIGPOLL },
76
#endif
77
    { NULL, -1 }
78
};
79
80
/*
81
 * Translate signal name to number.
82
 */
83
int
84
sudo_str2sig(const char *signame, int *result)
85
0
{
86
0
    struct sigalias *alias;
87
0
    const char *errstr;
88
0
    int signo;
89
90
    /* Could be a signal number encoded as a string. */
91
0
    if (isdigit((unsigned char)signame[0])) {
92
0
  signo = (int)sudo_strtonum(signame, 0, NSIG - 1, &errstr);
93
0
  if (errstr != NULL)
94
0
      return -1;
95
0
  *result = signo;
96
0
  return 0;
97
0
    }
98
99
    /* Check real-time signals. */
100
0
#if defined(SIGRTMIN)
101
0
    if (strncmp(signame, "RTMIN", 5) == 0) {
102
0
  if (signame[5] == '\0') {
103
0
      *result = SIGRTMIN;
104
0
      return 0;
105
0
  }
106
0
  if (signame[5] == '+') {
107
0
      if (isdigit((unsigned char)signame[6])) {
108
0
# ifdef _SC_RTSIG_MAX
109
0
    const long rtmax = sysconf(_SC_RTSIG_MAX);
110
# else
111
    const long rtmax = SIGRTMAX - SIGRTMIN;
112
# endif
113
0
    const int off = signame[6] - '0';
114
115
0
    if (rtmax > 0 && off < rtmax / 2) {
116
0
        *result = SIGRTMIN + off;
117
0
        return 0;
118
0
    }
119
0
      }
120
0
  }
121
0
    }
122
0
#endif
123
0
#if defined(SIGRTMAX)
124
0
    if (strncmp(signame, "RTMAX", 5) == 0) {
125
0
  if (signame[5] == '\0') {
126
0
      *result = SIGRTMAX;
127
0
      return 0;
128
0
  }
129
0
  if (signame[5] == '-') {
130
0
      if (isdigit((unsigned char)signame[6])) {
131
0
# ifdef _SC_RTSIG_MAX
132
0
    const long rtmax = sysconf(_SC_RTSIG_MAX);
133
# else
134
    const long rtmax = SIGRTMAX - SIGRTMIN;
135
# endif
136
0
    const int off = signame[6] - '0';
137
138
0
    if (rtmax > 0 && off < rtmax / 2) {
139
0
        *result = SIGRTMAX - off;
140
0
        return 0;
141
0
    }
142
0
      }
143
0
  }
144
0
    }
145
0
#endif
146
147
    /* Check aliases. */
148
0
    for (alias = sigaliases; alias->name != NULL; alias++) {
149
0
  if (strcmp(signame, alias->name) == 0) {
150
0
      *result = alias->number;
151
0
      return 0;
152
0
  }
153
0
    }
154
155
0
    for (signo = 1; signo < NSIG; signo++) {
156
0
  const char *cp = sigabbrev_np(signo);
157
0
  if (cp != NULL) {
158
      /* On macOS sys_signame[] may contain lower-case names. */
159
0
      if (strcasecmp(signame, cp) == 0) {
160
0
    *result = signo;
161
0
    return 0;
162
0
      }
163
0
  }
164
0
    }
165
166
0
    errno = EINVAL;
167
0
    return -1;
168
0
}
169
#endif /* HAVE_STR2SIG */