00001 /* 00002 syserrmsg 00003 Sec. 1.4.1 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #ifdef AUP1 00022 /* Copyright 1985 Advanced Programming Institute, Ltd. */ 00023 /*1-3*/ 00024 #include <stdio.h> 00025 00026 void syserr(const char *msg) /* print system call error message and terminate */ 00027 { 00028 extern int errno, sys_nerr; 00029 extern char *sys_errlist[]; 00030 00031 fprintf(stderr, "ERROR: %s (%d", msg, errno); 00032 if (errno > 0 && errno < sys_nerr) 00033 fprintf(stderr, "; %s)\n", sys_errlist[errno]); 00034 else 00035 fprintf(stderr, ")\n"); 00036 exit(EXIT_FAILURE); 00037 } 00038 /**/ 00039 #else 00040 00041 #define __EXTENSIONS__ 00042 #include "defs.h" 00043 00044 #include <netdb.h> 00045 00046 #if STD_UNIX_VERSION < SUV_SUS3 00047 #ifdef SOLARIS 00048 #undef __EXTENSIONS__ 00049 #endif 00050 #endif 00051 00052 /* 00053 Following appeared in the book, but now the more general function get_macrostr 00054 is used. It's in common/macrostr.c. 00055 */ 00056 /*[errcodes]*/ 00057 #if 0 /* skip errcodes */ 00058 static struct { 00059 int code; 00060 char *str; 00061 } errcodes[] = 00062 { 00063 { EPERM, "EPERM" }, 00064 { ENOENT, "ENOENT" }, 00065 { ESRCH, "ESRCH" }, 00066 { EINTR, "EINTR" }, 00067 { EIO, "EIO" }, 00068 { ENXIO, "ENXIO" }, 00069 { E2BIG, "E2BIG" }, 00070 { ENOEXEC, "ENOEXEC" }, 00071 { EBADF, "EBADF" }, 00072 { ECHILD, "ECHILD" }, 00073 { EAGAIN, "EAGAIN" }, 00074 { ENOMEM, "ENOMEM" }, 00075 { EACCES, "EACCES" }, 00076 { EFAULT, "EFAULT" }, 00077 { EBUSY, "EBUSY" }, 00078 { EEXIST, "EEXIST" }, 00079 { EXDEV, "EXDEV" }, 00080 { ENODEV, "ENODEV" }, 00081 { ENOTDIR, "ENOTDIR" }, 00082 { EISDIR, "EISDIR" }, 00083 { EINVAL, "EINVAL" }, 00084 { ENFILE, "ENFILE" }, 00085 { EMFILE, "EMFILE" }, 00086 { ENOTTY, "ENOTTY" }, 00087 { EFBIG, "EFBIG" }, 00088 { ENOSPC, "ENOSPC" }, 00089 { ESPIPE, "ESPIPE" }, 00090 { EROFS, "EROFS" }, 00091 { EMLINK, "EMLINK" }, 00092 { EPIPE, "EPIPE" }, 00093 { EDOM, "EDOM" }, 00094 { ERANGE, "ERANGE" }, 00095 { EDEADLK, "EDEADLK" }, 00096 { ENAMETOOLONG, "ENAMETOOLONG" }, 00097 { ENOLCK, "ENOLCK" }, 00098 { ENOSYS, "ENOSYS" }, 00099 { ENOTEMPTY, "ENOTEMPTY" }, 00100 #ifndef BSD_DERIVED /* Following are on LINUX; don't know yet about Solaris */ 00101 { ECHRNG, "ECHRNG" }, 00102 { EL2NSYNC, "EL2NSYNC" }, 00103 { EL3HLT, "EL3HLT" }, 00104 { EL3RST, "EL3RST" }, 00105 { ELNRNG, "ELNRNG" }, 00106 { EUNATCH, "EUNATCH" }, 00107 { ENOCSI, "ENOCSI" }, 00108 { EL2HLT, "EL2HLT" }, 00109 { EBADE, "EBADE" }, 00110 { EBADR, "EBADR" }, 00111 { EXFULL, "EXFULL" }, 00112 { ENOANO, "ENOANO" }, 00113 { EBADRQC, "EBADRQC" }, 00114 { EBADSLT, "EBADSLT" }, 00115 { EDEADLOCK, "EDEADLOCK" }, 00116 { EBFONT, "EBFONT" }, 00117 { ENOSTR, "ENOSTR" }, 00118 { ENODATA, "ENODATA" }, 00119 { ETIME, "ETIME" }, 00120 { ENOSR, "ENOSR" }, 00121 { ENONET, "ENONET" }, 00122 { ENOPKG, "ENOPKG" }, 00123 { ENOLINK, "ENOLINK" }, 00124 { EADV, "EADV" }, 00125 { ESRMNT, "ESRMNT" }, 00126 { ECOMM, "ECOMM" }, 00127 { EPROTO, "EPROTO" }, 00128 { EMULTIHOP, "EMULTIHOP" }, 00129 { EBADMSG, "EBADMSG" }, 00130 { ENOTUNIQ, "ENOTUNIQ" }, 00131 { EBADFD, "EBADFD" }, 00132 { EREMCHG, "EREMCHG" }, 00133 { ELIBACC, "ELIBACC" }, 00134 { ELIBBAD, "ELIBBAD" }, 00135 { ELIBSCN, "ELIBSCN" }, 00136 { ELIBMAX, "ELIBMAX" }, 00137 { ELIBEXEC, "ELIBEXEC" }, 00138 { ERESTART, "ERESTART" }, 00139 { ESTRPIPE, "ESTRPIPE" }, 00140 { EDQUOT, "EDQUOT" }, 00141 #ifndef SOLARIS 00142 { EDOTDOT, "EDOTDOT" }, 00143 { EUCLEAN, "EUCLEAN" }, 00144 { ENOTNAM, "ENOTNAM" }, 00145 { ENAVAIL, "ENAVAIL" }, 00146 { EISNAM, "EISNAM" }, 00147 { EREMOTEIO, "EREMOTEIO" }, 00148 { ENOMEDIUM, "ENOMEDIUM" }, 00149 { EMEDIUMTYPE, "EMEDIUMTYPE" }, 00150 #endif 00151 #endif 00152 #ifndef _POSIX_SOURCE 00153 { ENOTBLK, "ENOTBLK" }, 00154 { ETXTBSY, "ETXTBSY" }, 00155 { ENOTSOCK, "ENOTSOCK" }, 00156 { EDESTADDRREQ, "EDESTADDRREQ" }, 00157 { EMSGSIZE, "EMSGSIZE" }, 00158 { EPROTOTYPE, "EPROTOTYPE" }, 00159 { ENOPROTOOPT, "ENOPROTOOPT" }, 00160 { EPROTONOSUPPORT, "EPROTONOSUPPORT" }, 00161 { ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT" }, 00162 { EOPNOTSUPP, "EOPNOTSUPP" }, 00163 { EPFNOSUPPORT, "EPFNOSUPPORT" }, 00164 { EAFNOSUPPORT, "EAFNOSUPPORT" }, 00165 { EADDRINUSE, "EADDRINUSE" }, 00166 { EADDRNOTAVAIL, "EADDRNOTAVAIL" }, 00167 { ENETDOWN, "ENETDOWN" }, 00168 { ENETUNREACH, "ENETUNREACH" }, 00169 { ENETRESET, "ENETRESET" }, 00170 { ECONNABORTED, "ECONNABORTED" }, 00171 { ECONNRESET, "ECONNRESET" }, 00172 { ENOBUFS, "ENOBUFS" }, 00173 { EISCONN, "EISCONN" }, 00174 { ENOTCONN, "ENOTCONN" }, 00175 { ESHUTDOWN, "ESHUTDOWN" }, 00176 { ETOOMANYREFS, "ETOOMANYREFS" }, 00177 { ETIMEDOUT, "ETIMEDOUT" }, 00178 { ECONNREFUSED, "ECONNREFUSED" }, 00179 { ELOOP, "ELOOP" }, 00180 { EWOULDBLOCK, "EWOULDBLOCK" }, 00181 { EALREADY, "EALREADY" }, 00182 { EINPROGRESS, "EINPROGRESS" }, 00183 { EHOSTDOWN, "EHOSTDOWN" }, 00184 { EHOSTUNREACH, "EHOSTUNREACH" }, 00185 { ESTALE, "ESTALE" }, 00186 { EUSERS, "EUSERS" }, 00187 #ifndef DARWIN 00188 { ENOMSG, "ENOMSG" }, 00189 { EIDRM, "EIDRM" }, 00190 { EILSEQ, "EILSEQ" }, 00191 #endif /* DARWIN */ 00192 { EREMOTE, "EREMOTE" }, 00193 { EOVERFLOW, "EOVERFLOW" }, 00194 #endif 00195 { -EAI_AGAIN, "EAI_AGAIN" }, 00196 { -EAI_BADFLAGS, "EAI_BADFLAGS" }, 00197 { -EAI_FAIL, "EAI_FAIL" }, 00198 { -EAI_FAMILY, "EAI_FAMILY" }, 00199 { -EAI_MEMORY, "EAI_MEMORY" }, 00200 { -EAI_NONAME, "EAI_NONAME" }, 00201 { -EAI_SERVICE, "EAI_SERVICE" }, 00202 { -EAI_SOCKTYPE, "EAI_SOCKTYPE" }, 00203 { -EAI_SYSTEM, "EAI_SYSTEM" }, 00204 #ifdef EAI_OVERFLOW 00205 { -EAI_OVERFLOW, "EAI_OVERFLOW" }, 00206 #endif 00207 { EC_EINTERNAL, "EC_EINTERNAL" }, 00208 { 0, NULL} 00209 }; 00210 /*[errsymbol]*/ 00211 const char *errsymbol(int errno_arg) 00212 { 00213 int i; 00214 00215 for (i = 0; errcodes[i].str != NULL; i++) 00216 if (errcodes[i].code == errno_arg) 00217 return errcodes[i].str; 00218 return "[UnknownSymbol]"; 00219 } 00220 #endif /* skip errcodes */ 00221 const char *errsymbol(int errno_arg) 00222 { 00223 return get_macrostr("errno", errno_arg, NULL); 00224 } 00225 /*[]*/ 00226 char *syserrmsgline(char *buf, size_t buf_max, int errno_arg, EC_ERRTYPE type) 00227 { 00228 const char *errmsg; 00229 char *cat = "?"; 00230 00231 if (errno_arg == 0) 00232 snprintf(buf, buf_max, "No error"); 00233 else { 00234 if (errno_arg == EC_EINTERNAL) 00235 errmsg = "Internal error (nonstandard)"; 00236 else if (type == EC_EAI) { 00237 cat = "eai"; 00238 errmsg = gai_strerror(errno_arg); 00239 } 00240 else if (type == EC_GETDATE) 00241 errmsg = getdate_strerror(errno_arg); 00242 else { 00243 cat = "errno"; 00244 errmsg = strerror(errno_arg); 00245 } 00246 snprintf(buf, buf_max, "%s (%d: \"%s\")", 00247 get_macrostr(cat, errno_arg, NULL), errno_arg, 00248 errmsg != NULL ? errmsg : "no message string"); 00249 } 00250 return buf; 00251 } 00252 /* 00253 The book shows syserrmsg, which is now a macro that calls 00254 syserrmsgtype, because the latter has one additional argument. 00255 */ 00256 /*[syserrmsg-1]*/ 00257 char *syserrmsgtype(char *buf, size_t buf_max, const char *msg, 00258 int errno_arg, EC_ERRTYPE type) 00259 { 00260 const char *errmsg; 00261 char *cat = "?"; 00262 00263 if (msg == NULL) 00264 msg = "???"; 00265 if (errno_arg == 0) 00266 snprintf(buf, buf_max, "%s", msg); 00267 else { 00268 /*[]*/ 00269 if (errno_arg == EC_EINTERNAL) 00270 errmsg = "Internal error (nonstandard)"; 00271 else if (type == EC_EAI) { 00272 cat = "eai"; 00273 errmsg = gai_strerror(errno_arg); 00274 } 00275 else if (type == EC_GETDATE) 00276 errmsg = getdate_strerror(errno_arg); 00277 else { 00278 cat = "errno"; 00279 errmsg = strerror(errno_arg); 00280 } 00281 /*[syserrmsg-2]*/ 00282 /*errmsg = strerror(errno_arg);*/ 00283 snprintf(buf, buf_max, "%s\n\t\t*** %s (%d: \"%s\") ***", msg, 00284 get_macrostr(cat, errno_arg, NULL), errno_arg, 00285 errmsg != NULL ? errmsg : "no message string"); 00286 } 00287 return buf; 00288 } 00289 /*[]*/ 00290 00291 void syserr(const char *msg) /* print system call error message and terminate */ 00292 { 00293 syserr_print(msg); 00294 exit(EXIT_FAILURE); 00295 } 00296 /*[syserr_print]*/ 00297 void syserr_print(const char *msg) 00298 { 00299 char buf[200]; 00300 00301 fprintf(stderr, "ERROR: %s\n", syserrmsgtype(buf, sizeof(buf), msg, 00302 errno, EC_ERRNO)); 00303 } 00304 /*[]*/ 00305 00306 const char *getdate_strerror(int e) 00307 { 00308 const char *s[] = { 00309 "Invalid getdate_err value", 00310 "DATEMSK environment variable null or undefined", 00311 "Template file cannot be opened for reading", 00312 "Failed to get file status information", 00313 "Template file not a regular file", 00314 "I/O error encountered while reading template file", 00315 "Memory allocation failed", 00316 "No line in template that matches input", 00317 "Invalid input specification" 00318 }; 00319 if (e < 1 || e > 8) 00320 return s[0]; 00321 return s[e]; 00322 } 00323 #endif