1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 // G++ automatically defines _GNU_SOURCE, which then means that <string.h> 30 // gives us the GNU variant. 31 #undef _GNU_SOURCE 32 33 #include <string.h> 34 35 #include <errno.h> 36 #include <limits.h> 37 38 #include <async_safe/log.h> 39 40 #include "private/ErrnoRestorer.h" 41 42 #include <string.h> 43 44 #include "bionic/pthread_internal.h" 45 46 static const char* __sys_error_strings[] = { 47 [0] = "Success", 48 [EPERM] = "Operation not permitted", 49 [ENOENT] = "No such file or directory", 50 [ESRCH] = "No such process", 51 [EINTR] = "Interrupted system call", 52 [EIO] = "I/O error", 53 [ENXIO] = "No such device or address", 54 [E2BIG] = "Argument list too long", 55 [ENOEXEC] = "Exec format error", 56 [EBADF] = "Bad file descriptor", 57 [ECHILD] = "No child processes", 58 [EAGAIN] = "Try again", 59 [ENOMEM] = "Out of memory", 60 [EACCES] = "Permission denied", 61 [EFAULT] = "Bad address", 62 [ENOTBLK] = "Block device required", 63 [EBUSY] = "Device or resource busy", 64 [EEXIST] = "File exists", 65 [EXDEV] = "Cross-device link", 66 [ENODEV] = "No such device", 67 [ENOTDIR] = "Not a directory", 68 [EISDIR] = "Is a directory", 69 [EINVAL] = "Invalid argument", 70 [ENFILE] = "File table overflow", 71 [EMFILE] = "Too many open files", 72 [ENOTTY] = "Not a typewriter", 73 [ETXTBSY] = "Text file busy", 74 [EFBIG] = "File too large", 75 [ENOSPC] = "No space left on device", 76 [ESPIPE] = "Illegal seek", 77 [EROFS] = "Read-only file system", 78 [EMLINK] = "Too many links", 79 [EPIPE] = "Broken pipe", 80 [EDOM] = "Math argument out of domain of func", 81 [ERANGE] = "Math result not representable", 82 [EDEADLK] = "Resource deadlock would occur", 83 [ENAMETOOLONG] = "File name too long", 84 [ENOLCK] = "No record locks available", 85 [ENOSYS] = "Function not implemented", 86 [ENOTEMPTY] = "Directory not empty", 87 [ELOOP] = "Too many symbolic links encountered", 88 [ENOMSG] = "No message of desired type", 89 [EIDRM] = "Identifier removed", 90 [ECHRNG] = "Channel number out of range", 91 [EL2NSYNC] = "Level 2 not synchronized", 92 [EL3HLT] = "Level 3 halted", 93 [EL3RST] = "Level 3 reset", 94 [ELNRNG] = "Link number out of range", 95 [EUNATCH] = "Protocol driver not attached", 96 [ENOCSI] = "No CSI structure available", 97 [EL2HLT] = "Level 2 halted", 98 [EBADE] = "Invalid exchange", 99 [EBADR] = "Invalid request descriptor", 100 [EXFULL] = "Exchange full", 101 [ENOANO] = "No anode", 102 [EBADRQC] = "Invalid request code", 103 [EBADSLT] = "Invalid slot", 104 [EBFONT] = "Bad font file format", 105 [ENOSTR] = "Device not a stream", 106 [ENODATA] = "No data available", 107 [ETIME] = "Timer expired", 108 [ENOSR] = "Out of streams resources", 109 [ENONET] = "Machine is not on the network", 110 [ENOPKG] = "Package not installed", 111 [EREMOTE] = "Object is remote", 112 [ENOLINK] = "Link has been severed", 113 [EADV] = "Advertise error", 114 [ESRMNT] = "Srmount error", 115 [ECOMM] = "Communication error on send", 116 [EPROTO] = "Protocol error", 117 [EMULTIHOP] = "Multihop attempted", 118 [EDOTDOT] = "RFS specific error", 119 [EBADMSG] = "Not a data message", 120 [EOVERFLOW] = "Value too large for defined data type", 121 [ENOTUNIQ] = "Name not unique on network", 122 [EBADFD] = "File descriptor in bad state", 123 [EREMCHG] = "Remote address changed", 124 [ELIBACC] = "Can not access a needed shared library", 125 [ELIBBAD] = "Accessing a corrupted shared library", 126 [ELIBSCN] = ".lib section in a.out corrupted", 127 [ELIBMAX] = "Attempting to link in too many shared libraries", 128 [ELIBEXEC] = "Cannot exec a shared library directly", 129 [EILSEQ] = "Illegal byte sequence", 130 [ERESTART] = "Interrupted system call should be restarted", 131 [ESTRPIPE] = "Streams pipe error", 132 [EUSERS] = "Too many users", 133 [ENOTSOCK] = "Socket operation on non-socket", 134 [EDESTADDRREQ] = "Destination address required", 135 [EMSGSIZE] = "Message too long", 136 [EPROTOTYPE] = "Protocol wrong type for socket", 137 [ENOPROTOOPT] = "Protocol not available", 138 [EPROTONOSUPPORT] = "Protocol not supported", 139 [ESOCKTNOSUPPORT] = "Socket type not supported", 140 [EOPNOTSUPP] = "Operation not supported on transport endpoint", 141 [EPFNOSUPPORT] = "Protocol family not supported", 142 [EAFNOSUPPORT] = "Address family not supported by protocol", 143 [EADDRINUSE] = "Address already in use", 144 [EADDRNOTAVAIL] = "Cannot assign requested address", 145 [ENETDOWN] = "Network is down", 146 [ENETUNREACH] = "Network is unreachable", 147 [ENETRESET] = "Network dropped connection because of reset", 148 [ECONNABORTED] = "Software caused connection abort", 149 [ECONNRESET] = "Connection reset by peer", 150 [ENOBUFS] = "No buffer space available", 151 [EISCONN] = "Transport endpoint is already connected", 152 [ENOTCONN] = "Transport endpoint is not connected", 153 [ESHUTDOWN] = "Cannot send after transport endpoint shutdown", 154 [ETOOMANYREFS] = "Too many references: cannot splice", 155 [ETIMEDOUT] = "Connection timed out", 156 [ECONNREFUSED] = "Connection refused", 157 [EHOSTDOWN] = "Host is down", 158 [EHOSTUNREACH] = "No route to host", 159 [EALREADY] = "Operation already in progress", 160 [EINPROGRESS] = "Operation now in progress", 161 [ESTALE] = "Stale NFS file handle", 162 [EUCLEAN] = "Structure needs cleaning", 163 [ENOTNAM] = "Not a XENIX named type file", 164 [ENAVAIL] = "No XENIX semaphores available", 165 [EISNAM] = "Is a named type file", 166 [EREMOTEIO] = "Remote I/O error", 167 [EDQUOT] = "Quota exceeded", 168 [ENOMEDIUM] = "No medium found", 169 [EMEDIUMTYPE] = "Wrong medium type", 170 [ECANCELED] = "Operation Canceled", 171 [ENOKEY] = "Required key not available", 172 [EKEYEXPIRED] = "Key has expired", 173 [EKEYREVOKED] = "Key has been revoked", 174 [EKEYREJECTED] = "Key was rejected by service", 175 [EOWNERDEAD] = "Owner died", 176 [ENOTRECOVERABLE] = "State not recoverable", 177 [ERFKILL] = "Operation not possible due to RF-kill", 178 [EHWPOISON] = "Memory page has hardware error", 179 }; 180 181 static inline const char* __strerror_lookup(int error_number) { 182 if (error_number < 0 || error_number >= static_cast<int>(arraysize(__sys_error_strings))) { 183 return nullptr; 184 } 185 return __sys_error_strings[error_number]; 186 } 187 188 int strerror_r(int error_number, char* buf, size_t buf_len) { 189 ErrnoRestorer errno_restorer; 190 size_t length; 191 192 const char* error_name = __strerror_lookup(error_number); 193 if (error_name != nullptr) { 194 length = strlcpy(buf, error_name, buf_len); 195 } else { 196 length = async_safe_format_buffer(buf, buf_len, "Unknown error %d", error_number); 197 } 198 if (length >= buf_len) { 199 errno_restorer.override(ERANGE); 200 return -1; 201 } 202 203 return 0; 204 } 205 206 extern "C" char* __gnu_strerror_r(int error_number, char* buf, size_t buf_len) { 207 ErrnoRestorer errno_restorer; // The glibc strerror_r doesn't set errno if it truncates... 208 strerror_r(error_number, buf, buf_len); 209 return buf; // ...and just returns whatever fit. 210 } 211 212 char* strerror(int error_number) { 213 // Just return the original constant in the easy cases. 214 char* result = const_cast<char*>(__strerror_lookup(error_number)); 215 if (result != nullptr) { 216 return result; 217 } 218 219 bionic_tls& tls = __get_bionic_tls(); 220 result = tls.strerror_buf; 221 strerror_r(error_number, result, sizeof(tls.strerror_buf)); 222 return result; 223 } 224