1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "features.h" // for __weak
#include <errno.h> // for ERANGE, E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL
#include <libc.h> // for __unused
#include <string.h> // for memcpy, size_t, strerror, strlen, locale_t
char *strerror(int errnum)
{
char *table[] = {
[0] = "No error information",
[EILSEQ] = "Illegal byte sequence",
[EDOM] = "Domain error",
[ERANGE] = "Result not representable",
[ENOTTY] = "Not a tty",
[EACCES] = "Permission denied",
[EPERM] = "Operation not permitted",
[ENOENT] = "No such file or directory",
[ESRCH] = "No such process",
[EEXIST] = "File exists",
[EOVERFLOW] = "Value too large for data type",
[ENOSPC] = "No space left on device",
[ENOMEM] = "Out of memory",
[EBUSY] = "Resource busy",
[EINTR] = "Interrupted system call",
[EAGAIN] = "Resource temporarily unavailable",
[ESPIPE] = "Invalid seek",
[EXDEV] = "Cross-device link",
[EROFS] = "Read-only file system",
[ENOTEMPTY] = "Directory not empty",
[ECONNRESET] = "Connection reset by peer",
[ETIMEDOUT] = "Operation timed out",
[ECONNREFUSED] = "Connection refused",
[EHOSTDOWN] = "Host is down",
[EHOSTUNREACH] = "Host is unreachable",
[EADDRINUSE] = "Address in use",
[EPIPE] = "Broken pipe",
[EIO] = "I/O error",
[ENXIO] = "No such device or address",
[ENOTBLK] = "Block device required",
[ENODEV] = "No such device",
[ENOTDIR] = "Not a directory",
[EISDIR] = "Is a directory",
[ETXTBSY] = "Text file busy",
[ENOEXEC] = "Exec format error",
[EINVAL] = "Invalid argument",
[E2BIG] = "Argument list too long",
[ELOOP] = "Symbolic link loop",
[ENAMETOOLONG] = "Filename too long",
[ENFILE] = "Too many open files in system",
[EMFILE] = "No file descriptors available",
[EBADF] = "Bad file descriptor",
[ECHILD] = "No child process",
[EFAULT] = "Bad address",
[EFBIG] = "File too large",
[EMLINK] = "Too many links",
[ENOLCK] = "No locks available",
[EDEADLK] = "Resource deadlock would occur",
[ENOTRECOVERABLE] = "State not recoverable",
[EOWNERDEAD] = "Previous owner died",
[ECANCELED] = "Operation canceled",
[ENOSYS] = "Function not implemented",
[ENOMSG] = "No message of desired type",
[EIDRM] = "Identifier removed",
[ENOSTR] = "Device not a stream",
[ENODATA] = "No data available",
[ETIME] = "Device timeout",
[ENOSR] = "Out of streams resources",
[ENOLINK] = "Link has been severed",
[EPROTO] = "Protocol error",
[EBADMSG] = "Bad message",
[EBADFD] = "File descriptor in bad state",
[ENOTSOCK] = "Not a socket",
[EDESTADDRREQ] = "Destination address required",
[EMSGSIZE] = "Message too large",
[EPROTOTYPE] = "Protocol wrong type for socket",
[ENOPROTOOPT] = "Protocol not available",
[EPROTONOSUPPORT] = "Not supported",
[ESOCKTNOSUPPORT] = "Type not supported",
[ENOTSUP] = "Not supported",
[EPFNOSUPPORT] = "Protocol family not supported",
[EAFNOSUPPORT] = "Address family not supported by protocol",
[EADDRNOTAVAIL] = "Address not available",
[ENETDOWN] = "Network is down",
[ENETUNREACH] = "Network unreachable",
[ENETRESET] = "Connection reset by network",
[ECONNABORTED] = "Connection aborted",
[ENOBUFS] = "No buffer space available",
[EISCONN] = "Socket is connected",
[ENOTCONN] = "Socket not connected",
[ESHUTDOWN] = "Cannot send after socket shutdown",
[EALREADY] = "Operation already in progress",
[EINPROGRESS] = "Operation in progress",
[ESTALE] = "Stale file handle",
[EUCLEAN] = "Data consistency error",
[ENAVAIL] = "Resource not available",
[EREMOTEIO] = "Remote I/O error",
[EDQUOT] = "Quota exceeded",
[ENOMEDIUM] = "No medium found",
[EMEDIUMTYPE] = "Wrong medium type",
[EMULTIHOP] = "Multihop attempted",
[ENOKEY] = "Required key not available",
[EKEYEXPIRED] = "Key has expired",
[EKEYREVOKED] = "Key has been revoked",
[EKEYREJECTED] = "Key was rejected by service",
};
if (errnum < 0 || (size_t)errnum >= sizeof(table) / sizeof(table[0]) ||
!table[errnum]) {
errno = EINVAL;
return NULL;
}
return table[errnum];
}
int strerror_r(int errnum, char *buf, size_t buflen)
{
const char *msg = strerror(errnum);
size_t msglen = strlen(msg) + 1;
if (buflen < msglen) {
return ERANGE;
}
memcpy(buf, msg, msglen);
return 0;
}
__weak char *strerror_l(int errnum, locale_t __unused locale)
{
return strerror(errnum);
}
|