/* error.c : utility for looking up errno error numbers */ /* original version: 2006 June 27 * 2006 June 29 -- version 1.04 * contributers: Jon Mayo * No copyright claimed -- Public Domain */ /* TODO: convert error strings into error numbers/names */ #include #include #include #include #include #include #define T(x) if(e==(x)) return #x static const char **id_lookup_table; static unsigned id_max; static const char * err_id(int e) { #ifdef EPERM T(EPERM); #endif #ifdef ENOENT T(ENOENT); #endif #ifdef ESRCH T(ESRCH); #endif #ifdef EINTR T(EINTR); #endif #ifdef EIO T(EIO); #endif #ifdef ENXIO T(ENXIO); #endif #ifdef E2BIG T(E2BIG); #endif #ifdef ENOEXEC T(ENOEXEC); #endif #ifdef EBADF T(EBADF); #endif #ifdef ECHILD T(ECHILD); #endif #ifdef EAGAIN T(EAGAIN); #endif #ifdef ENOMEM T(ENOMEM); #endif #ifdef EACCES T(EACCES); #endif #ifdef EFAULT T(EFAULT); #endif #ifdef ENOTBLK T(ENOTBLK); #endif #ifdef EBUSY T(EBUSY); #endif #ifdef EEXIST T(EEXIST); #endif #ifdef EXDEV T(EXDEV); #endif #ifdef ENODEV T(ENODEV); #endif #ifdef ENOTDIR T(ENOTDIR); #endif #ifdef EISDIR T(EISDIR); #endif #ifdef EINVAL T(EINVAL); #endif #ifdef ENFILE T(ENFILE); #endif #ifdef EMFILE T(EMFILE); #endif #ifdef ENOTTY T(ENOTTY); #endif #ifdef ETXTBSY T(ETXTBSY); #endif #ifdef EFBIG T(EFBIG); #endif #ifdef ENOSPC T(ENOSPC); #endif #ifdef ESPIPE T(ESPIPE); #endif #ifdef EROFS T(EROFS); #endif #ifdef EMLINK T(EMLINK); #endif #ifdef EPIPE T(EPIPE); #endif #ifdef EDOM T(EDOM); #endif #ifdef ERANGE T(ERANGE); #endif #ifdef EDEADLK T(EDEADLK); #endif #ifdef ENAMETOOLONG T(ENAMETOOLONG); #endif #ifdef ENOLCK T(ENOLCK); #endif #ifdef ENOSYS T(ENOSYS); #endif #ifdef ENOTEMPTY T(ENOTEMPTY); #endif #ifdef ELOOP T(ELOOP); #endif #ifdef EWOULDBLOCK T(EWOULDBLOCK); #endif #ifdef ENOMSG T(ENOMSG); #endif #ifdef EIDRM T(EIDRM); #endif #ifdef ECHRNG T(ECHRNG); #endif #ifdef EL2NSYNC T(EL2NSYNC); #endif #ifdef EL3HLT T(EL3HLT); #endif #ifdef EL3RST T(EL3RST); #endif #ifdef ELNRNG T(ELNRNG); #endif #ifdef EUNATCH T(EUNATCH); #endif #ifdef ENOCSI T(ENOCSI); #endif #ifdef EL2HLT T(EL2HLT); #endif #ifdef EBADE T(EBADE); #endif #ifdef EBADR T(EBADR); #endif #ifdef EXFULL T(EXFULL); #endif #ifdef ENOANO T(ENOANO); #endif #ifdef EBADRQC T(EBADRQC); #endif #ifdef EBADSLT T(EBADSLT); #endif #ifdef EDEADLOCK T(EDEADLOCK); #endif #ifdef EBFONT T(EBFONT); #endif #ifdef ENOSTR T(ENOSTR); #endif #ifdef ENODATA T(ENODATA); #endif #ifdef ETIME T(ETIME); #endif #ifdef ENOSR T(ENOSR); #endif #ifdef ENONET T(ENONET); #endif #ifdef ENOPKG T(ENOPKG); #endif #ifdef EREMOTE T(EREMOTE); #endif #ifdef ENOLINK T(ENOLINK); #endif #ifdef EADV T(EADV); #endif #ifdef ESRMNT T(ESRMNT); #endif #ifdef ECOMM T(ECOMM); #endif #ifdef EPROTO T(EPROTO); #endif #ifdef EMULTIHOP T(EMULTIHOP); #endif #ifdef EDOTDOT T(EDOTDOT); #endif #ifdef EBADMSG T(EBADMSG); #endif #ifdef EOVERFLOW T(EOVERFLOW); #endif #ifdef ENOTUNIQ T(ENOTUNIQ); #endif #ifdef EBADFD T(EBADFD); #endif #ifdef EREMCHG T(EREMCHG); #endif #ifdef ELIBACC T(ELIBACC); #endif #ifdef ELIBBAD T(ELIBBAD); #endif #ifdef ELIBSCN T(ELIBSCN); #endif #ifdef ELIBMAX T(ELIBMAX); #endif #ifdef ELIBEXEC T(ELIBEXEC); #endif #ifdef EILSEQ T(EILSEQ); #endif #ifdef ERESTART T(ERESTART); #endif #ifdef ESTRPIPE T(ESTRPIPE); #endif #ifdef EUSERS T(EUSERS); #endif #ifdef ENOTSOCK T(ENOTSOCK); #endif #ifdef ETOOMANYREF T(ETOOMANYREF); #endif #ifdef TADDRREQ T(TADDRREQ); #endif #ifdef EMSGSIZE T(EMSGSIZE); #endif #ifdef EPROTOTYPE T(EPROTOTYPE); #endif #ifdef ENOPROTOOPT T(ENOPROTOOPT); #endif #ifdef EPROTONOSUPPORT T(EPROTONOSUPPORT); #endif #ifdef ESOCKTNOSUPPORT T(ESOCKTNOSUPPORT); #endif #ifdef EOPNOTSUPP T(EOPNOTSUPP); #endif #ifdef EPFNOSUPPORT T(EPFNOSUPPORT); #endif #ifdef EAFNOSUPPORT T(EAFNOSUPPORT); #endif #ifdef EADDRINUSE T(EADDRINUSE); #endif #ifdef EADDRNOTAVAIL T(EADDRNOTAVAIL); #endif #ifdef ENETDOWN T(ENETDOWN); #endif #ifdef ENETUNREACH T(ENETUNREACH); #endif #ifdef ENETRESET T(ENETRESET); #endif #ifdef ECONNABORTED T(ECONNABORTED); #endif #ifdef ECONNRESET T(ECONNRESET); #endif #ifdef ENOBUFS T(ENOBUFS); #endif #ifdef EISCONN T(EISCONN); #endif #ifdef ENOTCONN T(ENOTCONN); #endif #ifdef ESHUTDOWN T(ESHUTDOWN); #endif #ifdef ETOOMANYREFS T(ETOOMANYREFS); #endif #ifdef ECONNREFUSED T(ECONNREFUSED); #endif #ifdef EHOSTDOWN T(EHOSTDOWN); #endif #ifdef EHOSTUNREACH T(EHOSTUNREACH); #endif #ifdef EALREADY T(EALREADY); #endif #ifdef EINPROGRESS T(EINPROGRESS); #endif #ifdef ESTALE T(ESTALE); #endif #ifdef EUCLEAN T(EUCLEAN); #endif #ifdef ENOTNAM T(ENOTNAM); #endif #ifdef ENAVAIL T(ENAVAIL); #endif #ifdef EISNAM T(EISNAM); #endif #ifdef EREMOTEIO T(EREMOTEIO); #endif #ifdef EDQUOT T(EDQUOT); #endif #ifdef ENOMEDIUM T(ENOMEDIUM); #endif #ifdef EMEDIUMTYPE T(EMEDIUMTYPE); #endif #ifdef ECANCELED T(ECANCELED); #endif #ifdef ENOKEY T(ENOKEY); #endif #ifdef EKEYEXPIRED T(EKEYEXPIRED); #endif #ifdef EKEYREVOKED T(EKEYREVOKED); #endif #ifdef EKEYREJECTED T(EKEYREJECTED); #endif return 0; } /* attempt to guess the largest error value. assume gaps of 100 means that's the end of the list of errors */ static int guess_max(void) { int i; int miss_count; for(i = 0, miss_count = 0; i < INT_MAX; i++) { if(err_id(i)) { miss_count = 0; } else { miss_count++; if(miss_count > 100) break; } } return i - miss_count; } static void init_id_lookup_table(void) { unsigned i; id_max = guess_max(); id_lookup_table = calloc(sizeof * id_lookup_table, id_max + 1); for(i = 0; i <= id_max; i++) { id_lookup_table[i] = err_id(i); } } static int lookup_id_str(const char *str) { unsigned i; assert(id_lookup_table != NULL); assert(id_max > 0); for(i = 0; i <= id_max; i++) { if(id_lookup_table[i] && !strcmp(str, id_lookup_table[i])) { return i; } } return -1; } static void show_error(int e) { const char *id; id = err_id(e); if(!id) id = "???"; printf("%d:%s:%s\n", e, id, strerror(e)); } static void list_errors(void) { unsigned e; // fprintf(stderr, " max error: %d\n", max); assert(id_max > 0); for(e = 0; e <= id_max; e++) { const char *id = err_id(e); if (!id) continue; printf("%d:%s:%s\n", e, id, strerror(e)); } } int main(int argc, char **argv) { if (argc == 1) { usage: fprintf(stderr, "usage: %s [-l] \n", argv[0]); fprintf(stderr, " -l : list errors\n"); exit(1); } else { int i; init_id_lookup_table(); for(i = 1; i < argc; i++) { const char *arg = argv[i]; if (arg[0] == '-') { int j; for (j = 1; arg[j]; j++) { switch (arg[j]) { case 'l': list_errors(); exit(0); break; default: goto usage; } } continue; } int e; char *endptr; e = strtol(arg, &endptr, 10); if(!endptr || *endptr) { e = lookup_id_str(arg); if(e < 0) { fprintf(stderr, "error '%s' unknown.\n", arg); continue; } } if(e < 0) e = -e; show_error(e); } } return 0; }