13e12c5d1SDavid du Colombier #include "lib.h" 23e12c5d1SDavid du Colombier #include "sys9.h" 33e12c5d1SDavid du Colombier #include <string.h> 43e12c5d1SDavid du Colombier #include <errno.h> 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier /* make this global, so programs can look at it if errno is unilluminating */ 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier char _plan9err[ERRLEN]; 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier static struct errmap { 113e12c5d1SDavid du Colombier int errno; 123e12c5d1SDavid du Colombier char *ename; 133e12c5d1SDavid du Colombier } map[] = { 14*219b2ee8SDavid du Colombier /* from Brazil power errstr.h */ 153e12c5d1SDavid du Colombier {EINVAL, "never mind"}, 16*219b2ee8SDavid du Colombier {EINVAL, "inconsistent mount"}, 17*219b2ee8SDavid du Colombier {EINVAL, "not mounted"}, 18*219b2ee8SDavid du Colombier {EINVAL, "not in union"}, 19*219b2ee8SDavid du Colombier {EIO, "mount rpc error"}, 20*219b2ee8SDavid du Colombier {EIO, "mounted device shut down"}, 21*219b2ee8SDavid du Colombier {EPERM, "mounted directory forbids creation"}, 22*219b2ee8SDavid du Colombier {ENOENT, "file does not exist"}, 23*219b2ee8SDavid du Colombier {ENXIO, "unknown device in # filename"}, 24*219b2ee8SDavid du Colombier {ENOTDIR, "not a directory"}, 25*219b2ee8SDavid du Colombier {EISDIR, "file is a directory"}, 26*219b2ee8SDavid du Colombier {EINVAL, "bad character in file name"}, 27*219b2ee8SDavid du Colombier {EINVAL, "file name syntax"}, 28*219b2ee8SDavid du Colombier {EPERM, "permission denied"}, 293e12c5d1SDavid du Colombier {EPERM, "inappropriate use of fd"}, 303e12c5d1SDavid du Colombier {EINVAL, "bad arg in system call"}, 313e12c5d1SDavid du Colombier {EBUSY, "device or object already in use"}, 323e12c5d1SDavid du Colombier {EIO, "i/o error"}, 333e12c5d1SDavid du Colombier {EIO, "read or write too large"}, 343e12c5d1SDavid du Colombier {EIO, "read or write too small"}, 35*219b2ee8SDavid du Colombier {EINVAL, "bad network address"}, 36*219b2ee8SDavid du Colombier {EMSGSIZE, "message is too big for protocol"}, 37*219b2ee8SDavid du Colombier {EISCON, "network device is busy or allocated"}, 38*219b2ee8SDavid du Colombier {EPFNOSUPPORT, "network protocol not supported"}, 39*219b2ee8SDavid du Colombier {EADDRINUSE, "network port not available"}, 40*219b2ee8SDavid du Colombier {ENETDOWN, "bad interface or no free interface slots"}, 41*219b2ee8SDavid du Colombier {ENOTCONN, "not announced"}, 42*219b2ee8SDavid du Colombier {ESHUTDOWN, "write to hungup stream"}, 433e12c5d1SDavid du Colombier {EINVAL, "bad process or stream control request"}, 44*219b2ee8SDavid du Colombier {EBUSY, "no free devices"}, 45*219b2ee8SDavid du Colombier {EBUSY, "no free environment resources"}, 46*219b2ee8SDavid du Colombier {ESHUTDOWN, "mux server shut down"}, 47*219b2ee8SDavid du Colombier {EBUSY, "all mux channels busy"}, 48*219b2ee8SDavid du Colombier {EIO, "bad mux message format or mismatch"}, 49*219b2ee8SDavid du Colombier {ESRCH, "process exited"}, 50*219b2ee8SDavid du Colombier {ECHILD, "no living children"}, 51*219b2ee8SDavid du Colombier {EIO, "i/o error in demand load"}, 523e12c5d1SDavid du Colombier {ENOMEM, "virtual memory allocation failed"}, 53*219b2ee8SDavid du Colombier {EINVAL, "illegal line discipline"}, 54*219b2ee8SDavid du Colombier {EBADF, "fd out of range or not open"}, 553e12c5d1SDavid du Colombier {ESPIPE, "seek on a stream"}, 56*219b2ee8SDavid du Colombier {ENOEXEC, "exec header invalid"}, 57*219b2ee8SDavid du Colombier {ETIMEDOUT, "connection timed out"}, 58*219b2ee8SDavid du Colombier {ECONNREFUSED, "connection refused"}, 59*219b2ee8SDavid du Colombier {ENETUNREACH, "network unreachable"}, 60*219b2ee8SDavid du Colombier {EINTR, "interrupted"}, 61*219b2ee8SDavid du Colombier {ENETDOWN, "service required for tcp/udp/il calls"}, 62*219b2ee8SDavid du Colombier {ENOMEM, "kernel allocate failed"}, 63*219b2ee8SDavid du Colombier {ENOENT, "subfont not cached"}, 64*219b2ee8SDavid du Colombier {EINVAL, "segments overlap"}, 65*219b2ee8SDavid du Colombier {EINVAL, "mouse type already set"}, 66*219b2ee8SDavid du Colombier {EIO, "failed to recover fd"}, 67*219b2ee8SDavid du Colombier {EIO, "i/o count too small"}, 68*219b2ee8SDavid du Colombier {ENOMEM, "out of screen memory"}, 69*219b2ee8SDavid du Colombier {EGREG, "coherency problem"}, 70*219b2ee8SDavid du Colombier {EINVAL, "bad attach specifier"}, 71*219b2ee8SDavid du Colombier 72*219b2ee8SDavid du Colombier /* extra ones from Plan 9 power errstr.h */ 73*219b2ee8SDavid du Colombier {EINVAL, "bad bitblt or bitmap request"}, 74*219b2ee8SDavid du Colombier {EINVAL, "unallocated bitmap"}, 75*219b2ee8SDavid du Colombier {ENOMEM, "out of bitmap descriptors"}, 76*219b2ee8SDavid du Colombier {ENOMEM, "out of bitmap storage"}, 77*219b2ee8SDavid du Colombier {EINVAL, "unallocated font"}, 78*219b2ee8SDavid du Colombier {EGREG, "it's a thermal problem"}, 79*219b2ee8SDavid du Colombier 80*219b2ee8SDavid du Colombier /* from exhausted() calls in kernel */ 81*219b2ee8SDavid du Colombier {ENFILE, "no free file descriptors"}, 82*219b2ee8SDavid du Colombier {EBUSY, "no free mount devices"}, 83*219b2ee8SDavid du Colombier {EBUSY, "no free mount rpc buffer"}, 84*219b2ee8SDavid du Colombier {EBUSY, "no free segments"}, 85*219b2ee8SDavid du Colombier {ENOMEM, "no free memory"}, 86*219b2ee8SDavid du Colombier {ENOBUFS, "no free Blocks"}, 87*219b2ee8SDavid du Colombier {EBUSY, "no free routes"}, 883e12c5d1SDavid du Colombier 893e12c5d1SDavid du Colombier /* from ken */ 903e12c5d1SDavid du Colombier {EINVAL, "attach -- bad specifier"}, 913e12c5d1SDavid du Colombier {EBADF, "unknown fid"}, 923e12c5d1SDavid du Colombier {EINVAL, "bad character in directory name"}, 933e12c5d1SDavid du Colombier {EBADF, "read/write -- on non open fid"}, 943e12c5d1SDavid du Colombier {EIO, "read/write -- count too big"}, 953e12c5d1SDavid du Colombier {EIO, "phase error -- directory entry not allocated"}, 963e12c5d1SDavid du Colombier {EIO, "phase error -- qid does not match"}, 973e12c5d1SDavid du Colombier {EACCES, "access permission denied"}, 983e12c5d1SDavid du Colombier {ENOENT, "directory entry not found"}, 993e12c5d1SDavid du Colombier {EINVAL, "open/create -- unknown mode"}, 1003e12c5d1SDavid du Colombier {ENOTDIR, "walk -- in a non-directory"}, 1013e12c5d1SDavid du Colombier {ENOTDIR, "create -- in a non-directory"}, 1023e12c5d1SDavid du Colombier {EIO, "phase error -- cannot happen"}, 1033e12c5d1SDavid du Colombier {EEXIST, "create -- file exists"}, 1043e12c5d1SDavid du Colombier {EINVAL, "create -- . and .. illegal names"}, 1053e12c5d1SDavid du Colombier {ENOTEMPTY, "remove -- directory not empty"}, 1063e12c5d1SDavid du Colombier {EINVAL, "attach -- privileged user"}, 1073e12c5d1SDavid du Colombier {EPERM, "wstat -- not owner"}, 1083e12c5d1SDavid du Colombier {EPERM, "wstat -- not in group"}, 1093e12c5d1SDavid du Colombier {EINVAL, "create/wstat -- bad character in file name"}, 1103e12c5d1SDavid du Colombier {EBUSY, "walk -- too many (system wide)"}, 1113e12c5d1SDavid du Colombier {EROFS, "file system read only"}, 1123e12c5d1SDavid du Colombier {ENOSPC, "file system full"}, 1133e12c5d1SDavid du Colombier {EINVAL, "read/write -- offset negative"}, 1143e12c5d1SDavid du Colombier {EBUSY, "open/create -- file is locked"}, 1153e12c5d1SDavid du Colombier {EBUSY, "close/read/write -- lock is broken"}, 116*219b2ee8SDavid du Colombier 117*219b2ee8SDavid du Colombier /* from sockets */ 118*219b2ee8SDavid du Colombier {ENOTSOCK, "not a socket"}, 119*219b2ee8SDavid du Colombier {EPROTONOSUPPORT, "protocol not supported"}, 120*219b2ee8SDavid du Colombier {ECONNREFUSED, "connection refused"}, 121*219b2ee8SDavid du Colombier {EAFNOSUPPORT, "address family not supported"}, 122*219b2ee8SDavid du Colombier {ENOBUFS, "insufficient buffer space"}, 123*219b2ee8SDavid du Colombier {EOPNOTSUPP, "operation not supported"}, 124*219b2ee8SDavid du Colombier {EADDRINUSE, "address in use"}, 125*219b2ee8SDavid du Colombier {EGREG, "unnamed error message"}, 1263e12c5d1SDavid du Colombier }; 1273e12c5d1SDavid du Colombier 1283e12c5d1SDavid du Colombier #define NERRMAP (sizeof(map)/sizeof(struct errmap)) 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier /* convert last system call error to an errno */ 1313e12c5d1SDavid du Colombier void 1323e12c5d1SDavid du Colombier _syserrno(void) 1333e12c5d1SDavid du Colombier { 1343e12c5d1SDavid du Colombier int i; 1353e12c5d1SDavid du Colombier 1363e12c5d1SDavid du Colombier if(_ERRSTR(_plan9err) < 0) 137*219b2ee8SDavid du Colombier errno = EINVAL; 1383e12c5d1SDavid du Colombier for(i = 0; i < NERRMAP; i++) 1393e12c5d1SDavid du Colombier if(strcmp(_plan9err, map[i].ename) == 0) 1403e12c5d1SDavid du Colombier break; 141*219b2ee8SDavid du Colombier errno = (i < NERRMAP)? map[i].errno : EINVAL; 1423e12c5d1SDavid du Colombier } 143