1 #include "lib.h" 2 #include "sys9.h" 3 #include <string.h> 4 #include <errno.h> 5 6 /* make this global, so programs can look at it if errno is unilluminating */ 7 8 char _plan9err[ERRLEN]; 9 10 static struct errmap { 11 int errno; 12 char *ename; 13 } map[] = { 14 /* from Brazil power errstr.h */ 15 {EINVAL, "never mind"}, 16 {EINVAL, "inconsistent mount"}, 17 {EINVAL, "not mounted"}, 18 {EINVAL, "not in union"}, 19 {EIO, "mount rpc error"}, 20 {EIO, "mounted device shut down"}, 21 {EPERM, "mounted directory forbids creation"}, 22 {ENOENT, "file does not exist"}, 23 {ENXIO, "unknown device in # filename"}, 24 {ENOTDIR, "not a directory"}, 25 {EISDIR, "file is a directory"}, 26 {EINVAL, "bad character in file name"}, 27 {EINVAL, "file name syntax"}, 28 {EPERM, "permission denied"}, 29 {EPERM, "inappropriate use of fd"}, 30 {EINVAL, "bad arg in system call"}, 31 {EBUSY, "device or object already in use"}, 32 {EIO, "i/o error"}, 33 {EIO, "read or write too large"}, 34 {EIO, "read or write too small"}, 35 {EINVAL, "bad network address"}, 36 {EMSGSIZE, "message is too big for protocol"}, 37 {EISCON, "network device is busy or allocated"}, 38 {EPFNOSUPPORT, "network protocol not supported"}, 39 {EADDRINUSE, "network port not available"}, 40 {ENETDOWN, "bad interface or no free interface slots"}, 41 {ENOTCONN, "not announced"}, 42 {ESHUTDOWN, "write to hungup stream"}, 43 {EINVAL, "bad process or stream control request"}, 44 {EBUSY, "no free devices"}, 45 {EBUSY, "no free environment resources"}, 46 {ESHUTDOWN, "mux server shut down"}, 47 {EBUSY, "all mux channels busy"}, 48 {EIO, "bad mux message format or mismatch"}, 49 {ESRCH, "process exited"}, 50 {ECHILD, "no living children"}, 51 {EIO, "i/o error in demand load"}, 52 {ENOMEM, "virtual memory allocation failed"}, 53 {EINVAL, "illegal line discipline"}, 54 {EBADF, "fd out of range or not open"}, 55 {ESPIPE, "seek on a stream"}, 56 {ENOEXEC, "exec header invalid"}, 57 {ETIMEDOUT, "connection timed out"}, 58 {ECONNREFUSED, "connection refused"}, 59 {ENETUNREACH, "network unreachable"}, 60 {EINTR, "interrupted"}, 61 {ENETDOWN, "service required for tcp/udp/il calls"}, 62 {ENOMEM, "kernel allocate failed"}, 63 {ENOENT, "subfont not cached"}, 64 {EINVAL, "segments overlap"}, 65 {EINVAL, "mouse type already set"}, 66 {EIO, "failed to recover fd"}, 67 {EIO, "i/o count too small"}, 68 {ENOMEM, "out of screen memory"}, 69 {EGREG, "coherency problem"}, 70 {EINVAL, "bad attach specifier"}, 71 72 /* extra ones from Plan 9 power errstr.h */ 73 {EINVAL, "bad bitblt or bitmap request"}, 74 {EINVAL, "unallocated bitmap"}, 75 {ENOMEM, "out of bitmap descriptors"}, 76 {ENOMEM, "out of bitmap storage"}, 77 {EINVAL, "unallocated font"}, 78 {EGREG, "it's a thermal problem"}, 79 80 /* from exhausted() calls in kernel */ 81 {ENFILE, "no free file descriptors"}, 82 {EBUSY, "no free mount devices"}, 83 {EBUSY, "no free mount rpc buffer"}, 84 {EBUSY, "no free segments"}, 85 {ENOMEM, "no free memory"}, 86 {ENOBUFS, "no free Blocks"}, 87 {EBUSY, "no free routes"}, 88 89 /* from ken */ 90 {EINVAL, "attach -- bad specifier"}, 91 {EBADF, "unknown fid"}, 92 {EINVAL, "bad character in directory name"}, 93 {EBADF, "read/write -- on non open fid"}, 94 {EIO, "read/write -- count too big"}, 95 {EIO, "phase error -- directory entry not allocated"}, 96 {EIO, "phase error -- qid does not match"}, 97 {EACCES, "access permission denied"}, 98 {ENOENT, "directory entry not found"}, 99 {EINVAL, "open/create -- unknown mode"}, 100 {ENOTDIR, "walk -- in a non-directory"}, 101 {ENOTDIR, "create -- in a non-directory"}, 102 {EIO, "phase error -- cannot happen"}, 103 {EEXIST, "create -- file exists"}, 104 {EINVAL, "create -- . and .. illegal names"}, 105 {ENOTEMPTY, "remove -- directory not empty"}, 106 {EINVAL, "attach -- privileged user"}, 107 {EPERM, "wstat -- not owner"}, 108 {EPERM, "wstat -- not in group"}, 109 {EINVAL, "create/wstat -- bad character in file name"}, 110 {EBUSY, "walk -- too many (system wide)"}, 111 {EROFS, "file system read only"}, 112 {ENOSPC, "file system full"}, 113 {EINVAL, "read/write -- offset negative"}, 114 {EBUSY, "open/create -- file is locked"}, 115 {EBUSY, "close/read/write -- lock is broken"}, 116 117 /* from sockets */ 118 {ENOTSOCK, "not a socket"}, 119 {EPROTONOSUPPORT, "protocol not supported"}, 120 {ECONNREFUSED, "connection refused"}, 121 {EAFNOSUPPORT, "address family not supported"}, 122 {ENOBUFS, "insufficient buffer space"}, 123 {EOPNOTSUPP, "operation not supported"}, 124 {EADDRINUSE, "address in use"}, 125 {EGREG, "unnamed error message"}, 126 }; 127 128 #define NERRMAP (sizeof(map)/sizeof(struct errmap)) 129 130 /* convert last system call error to an errno */ 131 void 132 _syserrno(void) 133 { 134 int i; 135 136 if(_ERRSTR(_plan9err) < 0) 137 errno = EINVAL; 138 for(i = 0; i < NERRMAP; i++) 139 if(strcmp(_plan9err, map[i].ename) == 0) 140 break; 141 errno = (i < NERRMAP)? map[i].errno : EINVAL; 142 } 143