libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2009, 2010, 2013 Peter Miller 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU Lesser General Public License as 00007 * published by the Free Software Foundation; either version 3 of the 00008 * License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <libexplain/ac/signal.h> 00020 #include <libexplain/ac/string.h> 00021 00022 #include <libexplain/buffer/signal.h> 00023 #include <libexplain/parse_bits.h> 00024 #include <libexplain/sizeof.h> 00025 00026 00027 static explain_parse_bits_table_t table[] = 00028 { 00029 #ifdef SIGHUP 00030 { "SIGHUP", SIGHUP }, 00031 #endif 00032 #ifdef SIGINT 00033 { "SIGINT", SIGINT }, 00034 #endif 00035 #ifdef SIGQUIT 00036 { "SIGQUIT", SIGQUIT }, 00037 #endif 00038 #ifdef SIGILL 00039 { "SIGILL", SIGILL }, 00040 #endif 00041 #ifdef SIGABRT 00042 { "SIGABRT", SIGABRT }, 00043 #endif 00044 #ifdef SIGFPE 00045 { "SIGFPE", SIGFPE }, 00046 #endif 00047 #ifdef SIGKILL 00048 { "SIGKILL", SIGKILL }, 00049 #endif 00050 #ifdef SIGSEGV 00051 { "SIGSEGV", SIGSEGV }, 00052 #endif 00053 #ifdef SIGPIPE 00054 { "SIGPIPE", SIGPIPE }, 00055 #endif 00056 #ifdef SIGALRM 00057 { "SIGALRM", SIGALRM }, 00058 #endif 00059 #ifdef SIGTERM 00060 { "SIGTERM", SIGTERM }, 00061 #endif 00062 #ifdef SIGUSR1 00063 { "SIGUSR1", SIGUSR1 }, 00064 #endif 00065 #ifdef SIGUSR2 00066 { "SIGUSR2", SIGUSR2 }, 00067 #endif 00068 #ifdef SIGCHLD 00069 { "SIGCHLD", SIGCHLD }, 00070 #endif 00071 #ifdef SIGCONT 00072 { "SIGCONT", SIGCONT }, 00073 #endif 00074 #ifdef SIGSTOP 00075 { "SIGSTOP", SIGSTOP }, 00076 #endif 00077 #ifdef SIGTSTP 00078 { "SIGTSTP", SIGTSTP }, 00079 #endif 00080 #ifdef SIGTTIN 00081 { "SIGTTIN", SIGTTIN }, 00082 #endif 00083 #ifdef SIGTTOU 00084 { "SIGTTOU", SIGTTOU }, 00085 #endif 00086 00087 #ifdef SIGBUS 00088 { "SIGBUS", SIGBUS }, 00089 #endif 00090 #ifdef SIGPOLL 00091 { "SIGPOLL", SIGPOLL }, 00092 #endif 00093 #ifdef SIGPROF 00094 { "SIGPROF", SIGPROF }, 00095 #endif 00096 #ifdef SIGSYS 00097 { "SIGSYS", SIGSYS }, 00098 #endif 00099 #ifdef SIGTRAP 00100 { "SIGTRAP", SIGTRAP }, 00101 #endif 00102 #ifdef SIGURG 00103 { "SIGURG", SIGURG }, 00104 #endif 00105 #ifdef SIGVTALRM 00106 { "SIGVTALRM", SIGVTALRM }, 00107 #endif 00108 #ifdef SIGXCPU 00109 { "SIGXCPU", SIGXCPU }, 00110 #endif 00111 #ifdef SIGXFSZ 00112 { "SIGXFSZ", SIGXFSZ }, 00113 #endif 00114 00115 #ifdef SIGIOT 00116 { "SIGIOT", SIGIOT }, /* synonym for SIGABRT, must be in table after */ 00117 #endif 00118 #ifdef SIGEMT 00119 { "SIGEMT", SIGEMT }, 00120 #endif 00121 #ifdef SIGSTKFLT 00122 { "SIGSTKFLT", SIGSTKFLT }, 00123 #endif 00124 #ifdef SIGIO 00125 { "SIGIO", SIGIO }, 00126 #endif 00127 #ifdef SIGCLD 00128 { "SIGCLD", SIGCLD }, /* synonym for SIGCHLD, must be in table after */ 00129 #endif 00130 #ifdef SIGPWR 00131 { "SIGPWR", SIGPWR }, 00132 #endif 00133 #ifdef SIGLOST 00134 { "SIGLOST", SIGLOST }, /* synonym for SIGIO, must be after in table */ 00135 #endif 00136 #ifdef SIGWINCH 00137 { "SIGWINCH", SIGWINCH }, 00138 #endif 00139 #ifdef SIGUNUSED 00140 { "SIGUNUSED", SIGUNUSED }, /* may be synonym for SIGSYS, so table after */ 00141 #endif 00142 00143 #ifdef _NSIG 00144 { "_NSIG", _NSIG }, 00145 #endif 00146 00147 #if !defined(_SIGRTMIN) && !defined(__SIGRTMIN) 00148 /* sometimes this is a non-constant macro: sysconf(_SC_SIGRTMIN) */ 00149 { "SIGRTMIN", SIGRTMIN }, 00150 #endif 00151 #ifdef __SIGRTMIN 00152 { "SIGRTMIN", __SIGRTMIN }, 00153 { "__SIGRTMIN", __SIGRTMIN }, 00154 #endif 00155 #ifdef _SIGRTMIN 00156 { "SIGRTMIN", _SIGRTMIN }, 00157 { "_SIGRTMIN", _SIGRTMIN }, 00158 #endif 00159 00160 #if !defined(_SIGRTMAX) && !defined(__SIGRTMAX) 00161 /* sometimes this is a non-constant macro: sysconf(_SC_SIGRTMAX) */ 00162 { "SIGRTMAX", SIGRTMAX }, 00163 #endif 00164 #ifdef _SIGRTMAX 00165 { "SIGRTMAX", _SIGRTMAX }, 00166 { "_SIGRTMAX", _SIGRTMAX }, 00167 #endif 00168 #ifdef __SIGRTMAX 00169 { "SIGRTMAX", __SIGRTMAX }, 00170 { "__SIGRTMAX", __SIGRTMAX }, 00171 #endif 00172 }; 00173 00174 00175 static void 00176 fix_real_time_values(void) 00177 { 00178 #if defined(__SIGRTMIN) || defined(_SIGRTMIN) 00179 explain_parse_bits_table_t *tp; 00180 static int done; 00181 00182 if (done) 00183 return; 00184 done = 1; 00185 00186 /* 00187 * This is needed if SIGRTMIN et al are actually macros calling 00188 * sysconf(_SC_SIGRTMIN), etc. 00189 */ 00190 for (tp = table; tp < ENDOF(table); ++tp) 00191 { 00192 if (0 == strcmp(tp->name, "SIGRTMIN")) 00193 tp->value = SIGRTMIN; 00194 if (0 == strcmp(tp->name, "SIGRTMAX")) 00195 tp->value = SIGRTMAX; 00196 } 00197 #endif 00198 } 00199 00200 00201 void 00202 explain_buffer_signal(explain_string_buffer_t *sb, int signum) 00203 { 00204 const explain_parse_bits_table_t *tp; 00205 00206 fix_real_time_values(); 00207 tp = explain_parse_bits_find_by_value(signum, table, SIZEOF(table)); 00208 if (tp) 00209 { 00210 explain_string_buffer_puts(sb, tp->name); 00211 return; 00212 } 00213 00214 #if defined(SIGRTMIN) && defined(SIGRTMAX) 00215 { 00216 int rtmin; 00217 int rtmax; 00218 00219 /* 00220 * Don't worry about the SIGRTMIN+0 case being ugly, because the 00221 * table already dealt with that case. 00222 */ 00223 rtmin = SIGRTMIN; 00224 rtmax = SIGRTMAX; 00225 if (rtmin <= signum && signum <= rtmax) 00226 { 00227 explain_string_buffer_printf 00228 ( 00229 sb, 00230 "SIGRTMIN + %d", 00231 signum - rtmin 00232 ); 00233 return; 00234 } 00235 } 00236 #endif 00237 00238 explain_string_buffer_printf(sb, "%d", signum); 00239 } 00240 00241 00242 int 00243 explain_signal_parse_or_die(const char *text, const char *caption) 00244 { 00245 fix_real_time_values(); 00246 return explain_parse_bits_or_die(text, table, SIZEOF(table), caption); 00247 } 00248 00249 00250 /* vim: set ts=8 sw=4 et : */