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 /* see also: ../stdio/strerror.c, with errno-> string mapping */ 9 10 char _plan9err[ERRMAX]; 11 12 static struct errmap { 13 int errno; 14 char *ename; 15 } map[] = { 16 /* from /sys/src/9/port/errstr.h */ 17 {EINVAL, "inconsistent mount"}, 18 {EINVAL, "not mounted"}, 19 {EINVAL, "not in union"}, 20 {EIO, "mount rpc error"}, 21 {EIO, "mounted device shut down"}, 22 {EPERM, "mounted directory forbids creation"}, 23 {ENOENT, "does not exist"}, 24 {ENXIO, "unknown device in # filename"}, 25 {ENOTDIR, "not a directory"}, 26 {EISDIR, "file is a directory"}, 27 {EINVAL, "bad character in file name"}, 28 {EINVAL, "file name syntax"}, 29 {EPERM, "permission denied"}, 30 {EPERM, "inappropriate use of fd"}, 31 {EINVAL, "bad arg in system call"}, 32 {EBUSY, "device or object already in use"}, 33 {EIO, "i/o error"}, 34 {EIO, "read or write too large"}, 35 {EIO, "read or write too small"}, 36 {EADDRINUSE, "network port not available"}, 37 {ESHUTDOWN, "write to hungup stream"}, 38 {ESHUTDOWN, "i/o on hungup channel"}, 39 {EINVAL, "bad process or channel control request"}, 40 {EBUSY, "no free devices"}, 41 {ESRCH, "process exited"}, 42 {ECHILD, "no living children"}, 43 {EIO, "i/o error in demand load"}, 44 {ENOMEM, "virtual memory allocation failed"}, 45 {EBADF, "fd out of range or not open"}, 46 {EMFILE, "no free file descriptors"}, 47 {ESPIPE, "seek on a stream"}, 48 {ENOEXEC, "exec header invalid"}, 49 {ETIMEDOUT, "connection timed out"}, 50 {ECONNREFUSED, "connection refused"}, 51 {ECONNREFUSED, "connection in use"}, 52 {EINTR, "interrupted"}, 53 {ENOMEM, "kernel allocate failed"}, 54 {EINVAL, "segments overlap"}, 55 {EIO, "i/o count too small"}, 56 {EGREG, "ken has left the building"}, 57 {EINVAL, "bad attach specifier"}, 58 59 /* from exhausted() calls in kernel */ 60 {ENFILE, "no free file descriptors"}, 61 {EBUSY, "no free mount devices"}, 62 {EBUSY, "no free mount rpc buffer"}, 63 {EBUSY, "no free segments"}, 64 {ENOMEM, "no free memory"}, 65 {ENOBUFS, "no free Blocks"}, 66 {EBUSY, "no free routes"}, 67 68 /* from ken */ 69 {EINVAL, "attach -- bad specifier"}, 70 {EBADF, "unknown fid"}, 71 {EINVAL, "bad character in directory name"}, 72 {EBADF, "read/write -- on non open fid"}, 73 {EIO, "read/write -- count too big"}, 74 {EIO, "phase error -- directory entry not allocated"}, 75 {EIO, "phase error -- qid does not match"}, 76 {EACCES, "access permission denied"}, 77 {ENOENT, "directory entry not found"}, 78 {EINVAL, "open/create -- unknown mode"}, 79 {ENOTDIR, "walk -- in a non-directory"}, 80 {ENOTDIR, "create -- in a non-directory"}, 81 {EIO, "phase error -- cannot happen"}, 82 {EEXIST, "create -- file exists"}, 83 {EINVAL, "create -- . and .. illegal names"}, 84 {ENOTEMPTY, "remove -- directory not empty"}, 85 {EINVAL, "attach -- privileged user"}, 86 {EPERM, "wstat -- not owner"}, 87 {EPERM, "wstat -- not in group"}, 88 {EINVAL, "create/wstat -- bad character in file name"}, 89 {EBUSY, "walk -- too many (system wide)"}, 90 {EROFS, "file system read only"}, 91 {ENOSPC, "file system full"}, 92 {EINVAL, "read/write -- offset negative"}, 93 {EBUSY, "open/create -- file is locked"}, 94 {EBUSY, "close/read/write -- lock is broken"}, 95 96 /* from sockets */ 97 {ENOTSOCK, "not a socket"}, 98 {EPROTONOSUPPORT, "protocol not supported"}, 99 {ECONNREFUSED, "connection refused"}, 100 {EAFNOSUPPORT, "address family not supported"}, 101 {ENOBUFS, "insufficient buffer space"}, 102 {EOPNOTSUPP, "operation not supported"}, 103 {EADDRINUSE, "address in use"}, 104 {EGREG, "unnamed error message"}, 105 }; 106 107 #define NERRMAP (sizeof(map)/sizeof(struct errmap)) 108 109 /* convert last system call error to an errno */ 110 void 111 _syserrno(void) 112 { 113 int i; 114 115 if(_ERRSTR(_plan9err, sizeof _plan9err) < 0) 116 errno = EINVAL; 117 else{ 118 for(i = 0; i < NERRMAP; i++) 119 if(strstr(_plan9err, map[i].ename) != 0) 120 break; 121 _ERRSTR(_plan9err, sizeof _plan9err); 122 errno = (i < NERRMAP)? map[i].errno : EINVAL; 123 } 124 } 125