1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2025 Ricardo Branco <rbranco@suse.de> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <ctype.h> 30 #include <errno.h> 31 #include <signal.h> 32 #include <stdio.h> 33 #include <string.h> 34 35 #include <atf-c.h> 36 37 static void 38 test_roundtrip(int signum) 39 { 40 char str[SIG2STR_MAX]; 41 int sig; 42 43 ATF_REQUIRE_EQ_MSG(sig2str(signum, str), 0, 44 "sig2str(%d) failed", signum); 45 ATF_REQUIRE_EQ_MSG(str2sig(str, &sig), 0, 46 "str2sig(\"%s\") failed", str); 47 ATF_REQUIRE_INTEQ_MSG(sig, signum, 48 "Mismatch: roundtrip conversion gave %d instead of %d", 49 sig, signum); 50 } 51 52 ATF_TC_WITHOUT_HEAD(sig2str_valid); 53 ATF_TC_BODY(sig2str_valid, tc) 54 { 55 int sig; 56 57 for (sig = 1; sig < sys_nsig; sig++) { 58 test_roundtrip(sig); 59 } 60 } 61 62 ATF_TC_WITHOUT_HEAD(sig2str_invalid); 63 ATF_TC_BODY(sig2str_invalid, tc) 64 { 65 char buf[SIG2STR_MAX]; 66 67 ATF_CHECK(sig2str(0, buf) != 0); 68 ATF_CHECK(sig2str(-1, buf) != 0); 69 ATF_CHECK(sig2str(SIGRTMAX + 1, buf) != 0); 70 } 71 72 ATF_TC_WITHOUT_HEAD(str2sig_rtmin_rtmax); 73 ATF_TC_BODY(str2sig_rtmin_rtmax, tc) 74 { 75 int sig; 76 77 ATF_CHECK_MSG(str2sig("RTMIN", &sig) == 0, 78 "str2sig(\"RTMIN\") failed"); 79 ATF_CHECK_INTEQ_MSG(sig, SIGRTMIN, 80 "RTMIN mapped to %d, expected %d", sig, SIGRTMIN); 81 82 ATF_CHECK_MSG(str2sig("RTMAX", &sig) == 0, 83 "str2sig(\"RTMAX\") failed"); 84 ATF_CHECK_INTEQ_MSG(sig, SIGRTMAX, 85 "RTMAX mapped to %d, expected %d", sig, SIGRTMAX); 86 87 ATF_CHECK_MSG(str2sig("RTMIN+1", &sig) == 0, 88 "str2sig(\"RTMIN+1\") failed"); 89 ATF_CHECK_INTEQ_MSG(sig, SIGRTMIN + 1, 90 "RTMIN+1 mapped to %d, expected %d", sig, SIGRTMIN + 1); 91 92 ATF_CHECK_MSG(str2sig("RTMAX-1", &sig) == 0, 93 "str2sig(\"RTMAX-1\") failed"); 94 ATF_CHECK_INTEQ_MSG(sig, SIGRTMAX - 1, 95 "RTMAX-1 mapped to %d, expected %d", sig, SIGRTMAX - 1); 96 } 97 98 ATF_TC_WITHOUT_HEAD(str2sig_invalid_rt); 99 ATF_TC_BODY(str2sig_invalid_rt, tc) 100 { 101 int i, sig; 102 103 const char *invalid[] = { 104 "RTMIN+0", 105 "RTMAX-0", 106 "RTMIN-777", 107 "RTMIN+777", 108 "RTMAX-777", 109 "RTMAX+777", 110 "RTMIN-", 111 "RTMAX-", 112 "RTMIN0", 113 "RTMAX1", 114 "RTMIN+abc", 115 "RTMIN-abc", 116 NULL 117 }; 118 119 for (i = 0; invalid[i] != NULL; i++) { 120 ATF_CHECK_MSG(str2sig(invalid[i], &sig) != 0, 121 "str2sig(\"%s\") unexpectedly succeeded", invalid[i]); 122 } 123 } 124 125 ATF_TC_WITHOUT_HEAD(str2sig_fullname); 126 ATF_TC_BODY(str2sig_fullname, tc) 127 { 128 char fullname[SIG2STR_MAX + 3]; 129 int n, sig; 130 131 for (sig = 1; sig < sys_nsig; sig++) { 132 snprintf(fullname, sizeof(fullname), "SIG%s", sys_signame[sig]); 133 134 ATF_CHECK_MSG(str2sig(fullname, &n) == 0, 135 "str2sig(\"%s\") failed with errno %d (%s)", 136 fullname, errno, strerror(errno)); 137 138 ATF_CHECK_INTEQ_MSG(n, sig, 139 "Mismatch: %s = %d, str2sig(\"%s\") = %d", 140 sys_signame[sig], sig, fullname, n); 141 } 142 } 143 144 ATF_TC_WITHOUT_HEAD(str2sig_lowercase); 145 ATF_TC_BODY(str2sig_lowercase, tc) 146 { 147 char fullname[SIG2STR_MAX + 3]; 148 int n, sig; 149 150 for (sig = 1; sig < sys_nsig; sig++) { 151 snprintf(fullname, sizeof(fullname), "sig%s", sys_signame[sig]); 152 for (size_t i = 3; i < strlen(fullname); i++) 153 fullname[i] = toupper((unsigned char)fullname[i]); 154 155 ATF_CHECK_MSG(str2sig(fullname, &n) == 0, 156 "str2sig(\"%s\") failed with errno %d (%s)", 157 fullname, errno, strerror(errno)); 158 159 ATF_CHECK_INTEQ_MSG(n, sig, 160 "Mismatch: %s = %d, str2sig(\"%s\") = %d", 161 sys_signame[sig], sig, fullname, n); 162 } 163 } 164 165 ATF_TC_WITHOUT_HEAD(str2sig_numeric); 166 ATF_TC_BODY(str2sig_numeric, tc) 167 { 168 char buf[16]; 169 int n, sig; 170 171 for (sig = NSIG; sig < SIGRTMIN; sig++) { 172 snprintf(buf, sizeof(buf), "%d", sig); 173 ATF_CHECK_MSG(str2sig(buf, &n) == 0, 174 "str2sig(\"%s\") failed", buf); 175 ATF_CHECK_INTEQ_MSG(n, sig, 176 "Mismatch: str2sig(\"%s\") = %d, expected %d", 177 buf, n, sig); 178 } 179 } 180 181 ATF_TC_WITHOUT_HEAD(str2sig_invalid); 182 ATF_TC_BODY(str2sig_invalid, tc) 183 { 184 const char *invalid[] = { 185 "SIGDOESNOTEXIST", 186 "DOESNOTEXIST", 187 "INTERRUPT", 188 "", 189 "SIG", 190 "123abc", 191 "sig1extra", 192 NULL 193 }; 194 int i, sig; 195 196 for (i = 0; invalid[i] != NULL; i++) { 197 ATF_CHECK_MSG(str2sig(invalid[i], &sig) != 0, 198 "str2sig(\"%s\") unexpectedly succeeded", invalid[i]); 199 } 200 } 201 202 ATF_TP_ADD_TCS(tp) 203 { 204 ATF_TP_ADD_TC(tp, sig2str_valid); 205 ATF_TP_ADD_TC(tp, sig2str_invalid); 206 ATF_TP_ADD_TC(tp, str2sig_rtmin_rtmax); 207 ATF_TP_ADD_TC(tp, str2sig_invalid_rt); 208 ATF_TP_ADD_TC(tp, str2sig_fullname); 209 ATF_TP_ADD_TC(tp, str2sig_lowercase); 210 ATF_TP_ADD_TC(tp, str2sig_numeric); 211 ATF_TP_ADD_TC(tp, str2sig_invalid); 212 return (atf_no_error()); 213 } 214