libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2008-2010, 2013 Peter Miller 00004 * Written by Peter Miller <pmiller@opensource.org.au> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 3 of the License, or (at 00009 * your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <libexplain/ac/stddef.h> 00021 #include <libexplain/ac/stdlib.h> 00022 #include <libexplain/ac/string.h> 00023 #include <libexplain/ac/stdio.h> 00024 00025 #include <libexplain/gcc_attributes.h> 00026 00027 00028 /* 00029 * NAME 00030 * strerror - string for error number 00031 * 00032 * SYNOPSIS 00033 * char *strerror(int errnum); 00034 * 00035 * DESCRIPTION 00036 * The strerror function maps the error number in errnum to an error 00037 * message string. 00038 * 00039 * RETURNS 00040 * The strerror function returns a pointer to the string, the contents of 00041 * which are implementation-defined. The array pointed to shall not be 00042 * modified by the program, but may be overwritten by a subsequent call to 00043 * the strerror function. 00044 * 00045 * CAVEAT 00046 * Unknown errors will be rendered in the form "Error %d", where %d will 00047 * be replaced by a decimal representation of the error number. 00048 */ 00049 00050 #ifndef HAVE_STRERROR 00051 00052 LINKAGE_HIDDEN 00053 char * 00054 strerror(int n) 00055 { 00056 extern int sys_nerr; 00057 extern char *sys_errlist[]; 00058 static char buffer[16]; 00059 00060 if (n < 1 || n > sys_nerr) 00061 { 00062 sprintf(buffer, "Error %d", n); 00063 return buffer; 00064 } 00065 return sys_errlist[n]; 00066 } 00067 00068 #endif /* !HAVE_STRERROR */ 00069 00070 00071 #ifndef HAVE_STRCASECMP 00072 00073 LINKAGE_HIDDEN 00074 int 00075 strcasecmp(const char *s1, const char *s2) 00076 { 00077 int c1; 00078 int c2; 00079 00080 for (;;) 00081 { 00082 c1 = (unsigned char)*s1++; 00083 if (islower(c1)) 00084 c1 = toupper(c1); 00085 c2 = (unsigned char)*s2++; 00086 if (islower(c2)) 00087 c2 = toupper(c2); 00088 if (c1 != c2) 00089 { 00090 /* 00091 * if s1 is a leading substring of s2, must 00092 * return -1, even if the next character of s2 00093 * is negative. 00094 */ 00095 if (!c1) 00096 return -1; 00097 if (c1 < c2) 00098 return -1; 00099 return 1; 00100 } 00101 if (!c1) 00102 return 0; 00103 } 00104 } 00105 00106 #endif /* !HAVE_STRCASECMP */ 00107 00108 00109 #ifndef HAVE_STRSIGNAL 00110 00111 LINKAGE_HIDDEN 00112 char * 00113 strsignal(int n) 00114 { 00115 switch (n) 00116 { 00117 #ifdef SIGHUP 00118 case SIGHUP: 00119 return "hang up [SIGHUP]"; 00120 #endif /* SIGHUP */ 00121 00122 #ifdef SIGINT 00123 case SIGINT: 00124 return "user interrupt [SIGINT]"; 00125 #endif /* SIGINT */ 00126 00127 #ifdef SIGQUIT 00128 case SIGQUIT: 00129 return "user quit [SIGQUIT]"; 00130 #endif /* SIGQUIT */ 00131 00132 #ifdef SIGILL 00133 case SIGILL: 00134 return "illegal instruction [SIGILL]"; 00135 #endif /* SIGILL */ 00136 00137 #ifdef SIGTRAP 00138 case SIGTRAP: 00139 return "trace trap [SIGTRAP]"; 00140 #endif /* SIGTRAP */ 00141 00142 #ifdef SIGIOT 00143 case SIGIOT: 00144 return "abort [SIGIOT]"; 00145 #endif /* SIGIOT */ 00146 00147 #ifdef SIGEMT 00148 case SIGEMT: 00149 return "EMT instruction [SIGEMT]"; 00150 #endif /* SIGEMT */ 00151 00152 #ifdef SIGFPE 00153 case SIGFPE: 00154 return "floating point exception [SIGFPE]"; 00155 #endif /* SIGFPE */ 00156 00157 #ifdef SIGKILL 00158 case SIGKILL: 00159 return "kill [SIGKILL]"; 00160 #endif /* SIGKILL */ 00161 00162 #ifdef SIGBUS 00163 case SIGBUS: 00164 return "bus error [SIGBUS]"; 00165 #endif /* SIGBUS */ 00166 00167 #ifdef SIGSEGV 00168 case SIGSEGV: 00169 return "segmentation violation [SIGSEGV]"; 00170 #endif /* SIGSEGV */ 00171 00172 #ifdef SIGSYS 00173 case SIGSYS: 00174 return "bad argument to system call [SIGSYS]"; 00175 #endif /* SIGSYS */ 00176 00177 #ifdef SIGPIPE 00178 case SIGPIPE: 00179 return "write on a pipe with no one to read it [SIGPIPE]"; 00180 #endif /* SIGPIPE */ 00181 00182 #ifdef SIGALRM 00183 case SIGALRM: 00184 return "alarm clock [SIGALRM]"; 00185 #endif /* SIGALRM */ 00186 00187 #ifdef SIGTERM 00188 case SIGTERM: 00189 return "software termination [SIGTERM]"; 00190 #endif /* SIGTERM */ 00191 00192 #ifdef SIGUSR1 00193 case SIGUSR1: 00194 return "user defined signal one [SIGUSR1]"; 00195 #endif /* SIGUSR1 */ 00196 00197 #ifdef SIGUSR2 00198 case SIGUSR2: 00199 return "user defined signal two [SIGUSR2]"; 00200 #endif /* SIGUSR2 */ 00201 00202 #ifdef SIGCLD 00203 case SIGCLD: 00204 return "death of child [SIGCLD]"; 00205 #endif /* SIGCLD */ 00206 00207 #ifdef SIGPWR 00208 case SIGPWR: 00209 return "power failure [SIGPWR]"; 00210 #endif /* SIGPWR */ 00211 } 00212 return 0; 00213 } 00214 00215 #endif /* !HAVE_STRSIGNAL */ 00216 00217 00218 const char * 00219 explain_strsignal(int n) 00220 { 00221 static char buffer[16]; 00222 const char *s = strsignal(n); 00223 if (s && *s) 00224 return s; 00225 snprintf(buffer, sizeof(buffer), "signal %d", n); 00226 return buffer; 00227 } 00228 00229 00230 char * 00231 explain_strendcpy(char *dst, const char *src, const char *end) 00232 { 00233 if (dst < end) 00234 { 00235 /* leave room for terminating NUL */ 00236 end--; 00237 while (dst < end && *src) 00238 *dst++ = *src++; 00239 *dst = '\0'; 00240 if (*src) 00241 { 00242 /* return end parameter if truncated */ 00243 dst++; 00244 } 00245 } 00246 return dst; 00247 } 00248 00249 #ifndef HAVE_STRNSTR 00250 00251 /* this should have LINKAGE_HIDDEN except that codegen needs it */ 00252 00253 char * 00254 strnstr(const char *haystack, const char *needle, size_t haystack_size) 00255 { 00256 size_t needle_size; 00257 size_t j; 00258 00259 needle_size = strlen(needle); 00260 if (haystack_size < needle_size) 00261 return 0; 00262 for (j = 0; needle_size + j <= haystack_size; ++j) 00263 { 00264 if (0 == memcmp(haystack + j, needle, needle_size)) 00265 return (char *)(haystack + j); 00266 } 00267 return 0; 00268 } 00269 00270 #endif /* !HAVE_STRNSTR */ 00271 00272 00273 /* vim: set ts=8 sw=4 et : */