|
| 1 | +#include <errno.h> |
| 2 | +#include <stdio.h> |
| 3 | +#include <string.h> |
| 4 | +#include <ti/sprintf.h> |
| 5 | + |
| 6 | +static constexpr char errno_strings[] = { |
| 7 | + "no error" |
| 8 | + "\0" "EPERM" |
| 9 | + "\0" "EINVAL" |
| 10 | + "\0" "EIO" |
| 11 | + "\0" "EDOM" |
| 12 | + "\0" "ERANGE" |
| 13 | + "\0" "EILSEQ" |
| 14 | + /* C++ errno */ |
| 15 | + "\0" "E2BIG" |
| 16 | + "\0" "EACCES" |
| 17 | + "\0" "EADDRINUSE" |
| 18 | + "\0" "EADDRNOTAVAIL" |
| 19 | + "\0" "EAFNOSUPPORT" |
| 20 | + "\0" "EAGAIN" |
| 21 | + "\0" "EALREADY" |
| 22 | + "\0" "EBADF" |
| 23 | + "\0" "EBADMSG" |
| 24 | + "\0" "EBUSY" |
| 25 | + "\0" "ECANCELED" |
| 26 | + "\0" "ECHILD" |
| 27 | + "\0" "ECONNABORTED" |
| 28 | + "\0" "ECONNREFUSED" |
| 29 | + "\0" "ECONNRESET" |
| 30 | + "\0" "EDEADLK" |
| 31 | + "\0" "EDESTADDRREQ" |
| 32 | + "\0" "EEXIST" |
| 33 | + "\0" "EFAULT" |
| 34 | + "\0" "EFBIG" |
| 35 | + "\0" "EHOSTUNREACH" |
| 36 | + "\0" "EIDRM" |
| 37 | + "\0" "EINPROGRESS" |
| 38 | + "\0" "EINTR" |
| 39 | + "\0" "EISCONN" |
| 40 | + "\0" "EISDIR" |
| 41 | + "\0" "ELOOP" |
| 42 | + "\0" "EMFILE" |
| 43 | + "\0" "EMLINK" |
| 44 | + "\0" "EMSGSIZE" |
| 45 | + "\0" "ENAMETOOLONG" |
| 46 | + "\0" "ENETDOWN" |
| 47 | + "\0" "ENETRESET" |
| 48 | + "\0" "ENETUNREACH" |
| 49 | + "\0" "ENFILE" |
| 50 | + "\0" "ENOBUFS" |
| 51 | + "\0" "ENODATA" |
| 52 | + "\0" "ENODEV" |
| 53 | + "\0" "ENOENT" |
| 54 | + "\0" "ENOEXEC" |
| 55 | + "\0" "ENOLCK" |
| 56 | + "\0" "ENOLINK" |
| 57 | + "\0" "ENOMEM" |
| 58 | + "\0" "ENOMSG" |
| 59 | + "\0" "ENOPROTOOPT" |
| 60 | + "\0" "ENOSPC" |
| 61 | + "\0" "ENOSR" |
| 62 | + "\0" "ENOSTR" |
| 63 | + "\0" "ENOSYS" |
| 64 | + "\0" "ENOTCONN" |
| 65 | + "\0" "ENOTDIR" |
| 66 | + "\0" "ENOTEMPTY" |
| 67 | + "\0" "ENOTRECOVERABLE" |
| 68 | + "\0" "ENOTSOCK" |
| 69 | + "\0" "ENOTSUP" |
| 70 | + "\0" "ENOTTY" |
| 71 | + "\0" "ENXIO" |
| 72 | + "\0" "EOPNOTSUPP" |
| 73 | + "\0" "EOVERFLOW" |
| 74 | + "\0" "EOWNERDEAD" |
| 75 | + "\0" "EPIPE" |
| 76 | + "\0" "EPROTO" |
| 77 | + "\0" "EPROTONOSUPPORT" |
| 78 | + "\0" "EPROTOTYPE" |
| 79 | + "\0" "EROFS" |
| 80 | + "\0" "ESPIPE" |
| 81 | + "\0" "ESRCH" |
| 82 | + "\0" "ETIME" |
| 83 | + "\0" "ETIMEDOUT" |
| 84 | + "\0" "ETXTBSY" |
| 85 | + "\0" "EWOULDBLOCK" |
| 86 | + "\0" "EXDEV" |
| 87 | +}; |
| 88 | + |
| 89 | +static constexpr size_t count_errno_strings(const char *str, size_t size) |
| 90 | +{ |
| 91 | + size_t count = 0; |
| 92 | + for (size_t i = 0; i < size; i++) { |
| 93 | + if (str[i] == '\0') { |
| 94 | + ++count; |
| 95 | + } |
| 96 | + } |
| 97 | + return count; |
| 98 | +} |
| 99 | + |
| 100 | +static constexpr int errno_strings_count = count_errno_strings(errno_strings, sizeof(errno_strings)); |
| 101 | + |
| 102 | +static constexpr size_t unknown_errno_number_offset = 14; |
| 103 | +#define UNKNOWN_ERRNO_STRING "unknown error -8388608" |
| 104 | +static char unknown_errno_string[] = UNKNOWN_ERRNO_STRING; |
| 105 | + |
| 106 | +static_assert( |
| 107 | + UNKNOWN_ERRNO_STRING[unknown_errno_number_offset + 0] == '-' && |
| 108 | + UNKNOWN_ERRNO_STRING[unknown_errno_number_offset + 8] == '\0', |
| 109 | + "the string for unknown errno numbers has been changed" |
| 110 | +); |
| 111 | + |
| 112 | +char *strerror(int errnum) |
| 113 | +{ |
| 114 | + if (errnum < 0 || errnum >= errno_strings_count) { |
| 115 | + boot_sprintf(&unknown_errno_string[unknown_errno_number_offset], "%d", errnum); |
| 116 | + return const_cast<char*>(unknown_errno_string); |
| 117 | + } |
| 118 | + const char* ret = errno_strings; |
| 119 | + // worst case retrieval takes ~0.8ms (79 strings) |
| 120 | + for (int i = 0; i < errnum; i++) { |
| 121 | + // skips to the start of the next string |
| 122 | + ret += strlen(ret) + 1; |
| 123 | + } |
| 124 | + return const_cast<char*>(ret); |
| 125 | +} |
| 126 | + |
| 127 | +void perror(const char *str) |
| 128 | +{ |
| 129 | + /* Normally this would print to stderr, but since they are handled the same and pulling */ |
| 130 | + /* in fputs would create a dependency on fileioc, just use puts rather than fputs here */ |
| 131 | + |
| 132 | + if (str != nullptr && *str != '\0') { |
| 133 | + while (*str) { |
| 134 | + putchar(*str++); |
| 135 | + } |
| 136 | + putchar(':'); |
| 137 | + putchar(' '); |
| 138 | + } |
| 139 | + puts(strerror(errno)); |
| 140 | +} |
0 commit comments