]>
Commit | Line | Data |
---|---|---|
1fd5e000 CF |
1 | /* errno.cc: errno-related functions |
2 | ||
a7d2cc16 | 3 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
808aae3d | 4 | 2006, 2008, 2009, 2010, 2011 Red Hat, Inc. |
1fd5e000 CF |
5 | |
6 | This file is part of Cygwin. | |
7 | ||
8 | This software is a copyrighted work licensed under the terms of the | |
9 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
10 | details. */ | |
11 | ||
0476bae5 CF |
12 | #define _sys_nerr FOO_sys_nerr |
13 | #define sys_nerr FOOsys_nerr | |
066ca06f | 14 | #define _sys_errlist FOO_sys_errlist |
96b998db | 15 | #define strerror_r FOO_strerror_r |
4c8d72de | 16 | #include "winsup.h" |
29d52c8a | 17 | #include "cygtls.h" |
7cdcd90c | 18 | #include "ntdll.h" |
0476bae5 CF |
19 | #undef _sys_nerr |
20 | #undef sys_nerr | |
066ca06f | 21 | #undef _sys_errlist |
96b998db | 22 | #undef strerror_r |
1fd5e000 CF |
23 | |
24 | /* Table to map Windows error codes to Errno values. */ | |
25 | /* FIXME: Doing things this way is a little slow. It's trivial to change | |
26 | this into a big case statement if necessary. Left as is for now. */ | |
27 | ||
28 | #define X(w, e) {ERROR_##w, #w, e} | |
29 | ||
066ca06f CF |
30 | static NO_COPY struct |
31 | { | |
32 | DWORD w; /* windows version of error */ | |
33 | const char *s; /* text of windows version */ | |
34 | int e; /* errno version of error */ | |
35 | } errmap[] = | |
b92899cc CF |
36 | { |
37 | /* FIXME: Some of these choices are arbitrary! */ | |
b92899cc | 38 | X (ACCESS_DENIED, EACCES), |
06e0dc9a CF |
39 | X (ACTIVE_CONNECTIONS, EAGAIN), |
40 | X (ALREADY_EXISTS, EEXIST), | |
41 | X (BAD_DEVICE, ENODEV), | |
808aae3d | 42 | X (BAD_EXE_FORMAT, ENOEXEC), |
b98c66ee CV |
43 | X (BAD_NETPATH, ENOENT), |
44 | X (BAD_NET_NAME, ENOENT), | |
3498f76d | 45 | X (BAD_NET_RESP, ENOSYS), |
06e0dc9a CF |
46 | X (BAD_PATHNAME, ENOENT), |
47 | X (BAD_PIPE, EINVAL), | |
48 | X (BAD_UNIT, ENODEV), | |
49 | X (BAD_USERNAME, EINVAL), | |
50 | X (BEGINNING_OF_MEDIA, EIO), | |
b92899cc | 51 | X (BROKEN_PIPE, EPIPE), |
06e0dc9a CF |
52 | X (BUSY, EBUSY), |
53 | X (BUS_RESET, EIO), | |
b92899cc | 54 | X (CALL_NOT_IMPLEMENTED, ENOSYS), |
06e0dc9a | 55 | X (CANNOT_MAKE, EPERM), |
b92899cc | 56 | X (CHILD_NOT_COMPLETE, EBUSY), |
06e0dc9a CF |
57 | X (COMMITMENT_LIMIT, EAGAIN), |
58 | X (CRC, EIO), | |
59 | X (DEVICE_DOOR_OPEN, EIO), | |
60 | X (DEVICE_IN_USE, EAGAIN), | |
61 | X (DEVICE_REQUIRES_CLEANING, EIO), | |
62 | X (DIRECTORY, ENOTDIR), | |
b92899cc | 63 | X (DIR_NOT_EMPTY, ENOTEMPTY), |
06e0dc9a CF |
64 | X (DISK_CORRUPT, EIO), |
65 | X (DISK_FULL, ENOSPC), | |
66 | X (DUP_NAME, ENOTUNIQ), | |
50450dcc CV |
67 | X (EAS_DIDNT_FIT, ENOSPC), |
68 | X (EAS_NOT_SUPPORTED, ENOTSUP), | |
69 | X (EA_LIST_INCONSISTENT, EINVAL), | |
70 | X (EA_TABLE_FULL, ENOSPC), | |
06e0dc9a CF |
71 | X (END_OF_MEDIA, ENOSPC), |
72 | X (EOM_OVERFLOW, EIO), | |
808aae3d | 73 | X (EXE_MARKED_INVALID, ENOEXEC), |
06e0dc9a | 74 | X (FILEMARK_DETECTED, EIO), |
12f9fb49 | 75 | X (FILENAME_EXCED_RANGE, ENAMETOOLONG), |
50450dcc | 76 | X (FILE_CORRUPT, EEXIST), |
06e0dc9a CF |
77 | X (FILE_EXISTS, EEXIST), |
78 | X (FILE_INVALID, ENXIO), | |
79 | X (FILE_NOT_FOUND, ENOENT), | |
80 | X (HANDLE_DISK_FULL, ENOSPC), | |
81 | X (HANDLE_EOF, ENODATA), | |
82 | X (INVALID_ADDRESS, EINVAL), | |
83 | X (INVALID_AT_INTERRUPT_TIME, EINTR), | |
84 | X (INVALID_BLOCK_LENGTH, EIO), | |
85 | X (INVALID_DATA, EINVAL), | |
86 | X (INVALID_DRIVE, ENODEV), | |
50450dcc | 87 | X (INVALID_EA_NAME, EINVAL), |
808aae3d | 88 | X (INVALID_EXE_SIGNATURE, ENOEXEC), |
06e0dc9a CF |
89 | X (INVALID_FUNCTION, EBADRQC), |
90 | X (INVALID_HANDLE, EBADF), | |
91 | X (INVALID_NAME, ENOENT), | |
92 | X (INVALID_PARAMETER, EINVAL), | |
b92899cc | 93 | X (INVALID_SIGNAL_NUMBER, EINVAL), |
808aae3d | 94 | X (IOPL_NOT_ENABLED, ENOEXEC), |
06e0dc9a CF |
95 | X (IO_DEVICE, EIO), |
96 | X (IO_PENDING, EAGAIN), | |
97 | X (LOCK_VIOLATION, EACCES), | |
98 | X (MAX_THRDS_REACHED, EAGAIN), | |
99 | X (META_EXPANSION_TOO_LONG, EINVAL), | |
f82ca06e | 100 | X (MOD_NOT_FOUND, ENOENT), |
d6b1ac7f | 101 | X (MORE_DATA, EMSGSIZE), |
06e0dc9a | 102 | X (NEGATIVE_SEEK, EINVAL), |
b98c66ee | 103 | X (NETNAME_DELETED, ENOENT), |
06e0dc9a CF |
104 | X (NOACCESS, EFAULT), |
105 | X (NONPAGED_SYSTEM_RESOURCES, EAGAIN), | |
9a512577 | 106 | X (NONE_MAPPED, EINVAL), |
b92899cc | 107 | X (NOT_CONNECTED, ENOLINK), |
06e0dc9a | 108 | X (NOT_ENOUGH_MEMORY, ENOMEM), |
b92899cc | 109 | X (NOT_OWNER, EPERM), |
b92899cc | 110 | X (NOT_READY, ENOMEDIUM), |
06e0dc9a CF |
111 | X (NOT_SAME_DEVICE, EXDEV), |
112 | X (NOT_SUPPORTED, ENOSYS), | |
113 | X (NO_DATA, EPIPE), | |
114 | X (NO_DATA_DETECTED, EIO), | |
dee56309 | 115 | X (NO_MEDIA_IN_DRIVE, ENOMEDIUM), |
06e0dc9a | 116 | X (NO_MORE_FILES, ENMFILE), |
b4b0980b | 117 | X (NO_MORE_ITEMS, ENMFILE), |
06e0dc9a CF |
118 | X (NO_MORE_SEARCH_HANDLES, ENFILE), |
119 | X (NO_PROC_SLOTS, EAGAIN), | |
120 | X (NO_SIGNAL_SENT, EIO), | |
779ece3c | 121 | X (NO_SYSTEM_RESOURCES, EFBIG), |
06e0dc9a CF |
122 | X (NO_TOKEN, EINVAL), |
123 | X (OPEN_FAILED, EIO), | |
124 | X (OPEN_FILES, EAGAIN), | |
125 | X (OUTOFMEMORY, ENOMEM), | |
12a41013 | 126 | X (PAGED_SYSTEM_RESOURCES, EAGAIN), |
12a41013 | 127 | X (PAGEFILE_QUOTA, EAGAIN), |
06e0dc9a CF |
128 | X (PATH_NOT_FOUND, ENOENT), |
129 | X (PIPE_BUSY, EBUSY), | |
130 | X (PIPE_CONNECTED, EBUSY), | |
131 | X (PIPE_LISTENING, ECOMM), | |
132 | X (PIPE_NOT_CONNECTED, ECOMM), | |
133 | X (POSSIBLE_DEADLOCK, EDEADLOCK), | |
134 | X (PROCESS_ABORTED, EFAULT), | |
135 | X (PROC_NOT_FOUND, ESRCH), | |
136 | X (REM_NOT_LIST, ENONET), | |
137 | X (SETMARK_DETECTED, EIO), | |
138 | X (SHARING_BUFFER_EXCEEDED, ENOLCK), | |
139 | X (SHARING_VIOLATION, EBUSY), | |
140 | X (SIGNAL_PENDING, EBUSY), | |
141 | X (SIGNAL_REFUSED, EIO), | |
142 | X (THREAD_1_INACTIVE, EINVAL), | |
143 | X (TOO_MANY_LINKS, EMLINK), | |
144 | X (TOO_MANY_OPEN_FILES, EMFILE), | |
145 | X (WAIT_NO_CHILDREN, ECHILD), | |
146 | X (WORKING_SET_QUOTA, EAGAIN), | |
147 | X (WRITE_PROTECT, EROFS), | |
6c22c79f CV |
148 | X (SEEK, EINVAL), |
149 | X (SECTOR_NOT_FOUND, EINVAL), | |
fee56469 | 150 | X (IO_INCOMPLETE, EAGAIN), |
b92899cc CF |
151 | { 0, NULL, 0} |
152 | }; | |
153 | ||
0476bae5 | 154 | extern "C" { |
c4ca0e80 | 155 | const char *_sys_errlist[] NO_COPY_INIT = |
1fd5e000 | 156 | { |
b9188d6c CV |
157 | /* NOERROR 0 */ "No error", |
158 | /* EPERM 1 */ "Operation not permitted", | |
159 | /* ENOENT 2 */ "No such file or directory", | |
160 | /* ESRCH 3 */ "No such process", | |
161 | /* EINTR 4 */ "Interrupted system call", | |
162 | /* EIO 5 */ "Input/Output error", | |
163 | /* ENXIO 6 */ "No such device or address", | |
164 | /* E2BIG 7 */ "Argument list too long", | |
165 | /* ENOEXEC 8 */ "Exec format error", | |
166 | /* EBADF 9 */ "Bad file descriptor", | |
167 | /* ECHILD 10 */ "No child processes", | |
168 | /* EAGAIN 11 */ "Resource temporarily unavailable", | |
169 | /* ENOMEM 12 */ "Cannot allocate memory", | |
170 | /* EACCES 13 */ "Permission denied", | |
171 | /* EFAULT 14 */ "Bad address", | |
172 | /* ENOTBLK 15 */ "Block device required", | |
173 | /* EBUSY 16 */ "Device or resource busy", | |
174 | /* EEXIST 17 */ "File exists", | |
175 | /* EXDEV 18 */ "Invalid cross-device link", | |
176 | /* ENODEV 19 */ "No such device", | |
177 | /* ENOTDIR 20 */ "Not a directory", | |
178 | /* EISDIR 21 */ "Is a directory", | |
179 | /* EINVAL 22 */ "Invalid argument", | |
180 | /* ENFILE 23 */ "Too many open files in system", | |
181 | /* EMFILE 24 */ "Too many open files", | |
182 | /* ENOTTY 25 */ "Inappropriate ioctl for device", | |
183 | /* ETXTBSY 26 */ "Text file busy", | |
184 | /* EFBIG 27 */ "File too large", | |
185 | /* ENOSPC 28 */ "No space left on device", | |
186 | /* ESPIPE 29 */ "Illegal seek", | |
187 | /* EROFS 30 */ "Read-only file system", | |
188 | /* EMLINK 31 */ "Too many links", | |
189 | /* EPIPE 32 */ "Broken pipe", | |
190 | /* EDOM 33 */ "Numerical argument out of domain", | |
191 | /* ERANGE 34 */ "Numerical result out of range", | |
192 | /* ENOMSG 35 */ "No message of desired type", | |
193 | /* EIDRM 36 */ "Identifier removed", | |
194 | /* ECHRNG 37 */ "Channel number out of range", | |
195 | /* EL2NSYNC 38 */ "Level 2 not synchronized", | |
196 | /* EL3HLT 39 */ "Level 3 halted", | |
197 | /* EL3RST 40 */ "Level 3 reset", | |
198 | /* ELNRNG 41 */ "Link number out of range", | |
199 | /* EUNATCH 42 */ "Protocol driver not attached", | |
200 | /* ENOCSI 43 */ "No CSI structure available", | |
201 | /* EL2HLT 44 */ "Level 2 halted", | |
202 | /* EDEADLK 45 */ "Resource deadlock avoided", | |
203 | /* ENOLCK 46 */ "No locks available", | |
3c9abad5 EB |
204 | NULL, |
205 | NULL, | |
206 | NULL, | |
b9188d6c CV |
207 | /* EBADE 50 */ "Invalid exchange", |
208 | /* EBADR 51 */ "Invalid request descriptor", | |
209 | /* EXFULL 52 */ "Exchange full", | |
210 | /* ENOANO 53 */ "No anode", | |
211 | /* EBADRQC 54 */ "Invalid request code", | |
212 | /* EBADSLT 55 */ "Invalid slot", | |
213 | /* EDEADLOCK 56 */ "File locking deadlock error", | |
214 | /* EBFONT 57 */ "Bad font file format", | |
3c9abad5 EB |
215 | NULL, |
216 | NULL, | |
b9188d6c CV |
217 | /* ENOSTR 60 */ "Device not a stream", |
218 | /* ENODATA 61 */ "No data available", | |
219 | /* ETIME 62 */ "Timer expired", | |
220 | /* ENOSR 63 */ "Out of streams resources", | |
221 | /* ENONET 64 */ "Machine is not on the network", | |
222 | /* ENOPKG 65 */ "Package not installed", | |
223 | /* EREMOTE 66 */ "Object is remote", | |
224 | /* ENOLINK 67 */ "Link has been severed", | |
225 | /* EADV 68 */ "Advertise error", | |
226 | /* ESRMNT 69 */ "Srmount error", | |
227 | /* ECOMM 70 */ "Communication error on send", | |
228 | /* EPROTO 71 */ "Protocol error", | |
3c9abad5 EB |
229 | NULL, |
230 | NULL, | |
b9188d6c CV |
231 | /* EMULTIHOP 74 */ "Multihop attempted", |
232 | /* ELBIN 75 */ "Inode is remote (not really error)", | |
233 | /* EDOTDOT 76 */ "RFS specific error", | |
234 | /* EBADMSG 77 */ "Bad message", | |
3c9abad5 | 235 | NULL, |
b9188d6c CV |
236 | /* EFTYPE 79 */ "Inappropriate file type or format", |
237 | /* ENOTUNIQ 80 */ "Name not unique on network", | |
238 | /* EBADFD 81 */ "File descriptor in bad state", | |
239 | /* EREMCHG 82 */ "Remote address changed", | |
240 | /* ELIBACC 83 */ "Can not access a needed shared library", | |
241 | /* ELIBBAD 84 */ "Accessing a corrupted shared library", | |
242 | /* ELIBSCN 85 */ ".lib section in a.out corrupted", | |
243 | /* ELIBMAX 86 */ "Attempting to link in too many shared libraries", | |
244 | /* ELIBEXEC 87 */ "Cannot exec a shared library directly", | |
245 | /* ENOSYS 88 */ "Function not implemented", | |
246 | /* ENMFILE 89 */ "No more files", | |
247 | /* ENOTEMPTY 90 */ "Directory not empty", | |
248 | /* ENAMETOOLONG 91 */ "File name too long", | |
249 | /* ELOOP 92 */ "Too many levels of symbolic links", | |
3c9abad5 EB |
250 | NULL, |
251 | NULL, | |
b9188d6c CV |
252 | /* EOPNOTSUPP 95 */ "Operation not supported", |
253 | /* EPFNOSUPPORT 96 */ "Protocol family not supported", | |
3c9abad5 EB |
254 | NULL, |
255 | NULL, | |
256 | NULL, | |
257 | NULL, | |
258 | NULL, | |
259 | NULL, | |
260 | NULL, | |
b9188d6c CV |
261 | /* ECONNRESET 104 */ "Connection reset by peer", |
262 | /* ENOBUFS 105 */ "No buffer space available", | |
263 | /* EAFNOSUPPORT 106 */ "Address family not supported by protocol", | |
264 | /* EPROTOTYPE 107 */ "Protocol wrong type for socket", | |
ddf87001 | 265 | /* ENOTSOCK 108 */ "Socket operation on non-socket", |
b9188d6c CV |
266 | /* ENOPROTOOPT 109 */ "Protocol not available", |
267 | /* ESHUTDOWN 110 */ "Cannot send after transport endpoint shutdown", | |
268 | /* ECONNREFUSED 111 */ "Connection refused", | |
269 | /* EADDRINUSE 112 */ "Address already in use", | |
270 | /* ECONNABORTED 113 */ "Software caused connection abort", | |
271 | /* ENETUNREACH 114 */ "Network is unreachable", | |
272 | /* ENETDOWN 115 */ "Network is down", | |
273 | /* ETIMEDOUT 116 */ "Connection timed out", | |
274 | /* EHOSTDOWN 117 */ "Host is down", | |
275 | /* EHOSTUNREACH 118 */ "No route to host", | |
276 | /* EINPROGRESS 119 */ "Operation now in progress", | |
277 | /* EALREADY 120 */ "Operation already in progress", | |
278 | /* EDESTADDRREQ 121 */ "Destination address required", | |
279 | /* EMSGSIZE 122 */ "Message too long", | |
1fd5e000 CF |
280 | /* EPROTONOSUPPORT 123 */ "Protocol not supported", |
281 | /* ESOCKTNOSUPPORT 124 */ "Socket type not supported", | |
b9188d6c CV |
282 | /* EADDRNOTAVAIL 125 */ "Cannot assign requested address", |
283 | /* ENETRESET 126 */ "Network dropped connection on reset", | |
284 | /* EISCONN 127 */ "Transport endpoint is already connected", | |
285 | /* ENOTCONN 128 */ "Transport endpoint is not connected", | |
286 | /* ETOOMANYREFS 129 */ "Too many references: cannot splice", | |
287 | /* EPROCLIM 130 */ "Too many processes", | |
288 | /* EUSERS 131 */ "Too many users", | |
289 | /* EDQUOT 132 */ "Disk quota exceeded", | |
290 | /* ESTALE 133 */ "Stale NFS file handle", | |
ddf87001 | 291 | /* ENOTSUP 134 */ "Not supported", |
b9188d6c | 292 | /* ENOMEDIUM 135 */ "No medium found", |
ddf87001 | 293 | /* ENOSHARE 136 */ "No such host or network path", |
b9188d6c CV |
294 | /* ECASECLASH 137 */ "Filename exists with different case", |
295 | /* EILSEQ 138 */ "Invalid or incomplete multibyte or wide character", | |
ddf87001 EB |
296 | /* EOVERFLOW 139 */ "Value too large for defined data type", |
297 | /* ECANCELED 140 */ "Operation canceled", | |
298 | /* ENOTRECOVERABLE 141 */ "State not recoverable", | |
99438c63 CV |
299 | /* EOWNERDEAD 142 */ "Previous owner died", |
300 | /* ESTRPIPE 143 */ "Streams pipe error" | |
1fd5e000 CF |
301 | }; |
302 | ||
066ca06f | 303 | int NO_COPY_INIT _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]); |
0476bae5 | 304 | }; |
1fd5e000 | 305 | |
066ca06f CF |
306 | int __stdcall |
307 | geterrno_from_win_error (DWORD code, int deferrno) | |
308 | { | |
309 | for (int i = 0; errmap[i].w != 0; ++i) | |
310 | if (code == errmap[i].w) | |
311 | { | |
312 | syscall_printf ("windows error %u == errno %d", code, errmap[i].e); | |
313 | return errmap[i].e; | |
314 | } | |
315 | ||
316 | syscall_printf ("unknown windows error %u, setting errno to %d", code, | |
317 | deferrno); | |
318 | return deferrno; /* FIXME: what's so special about EACCESS? */ | |
319 | } | |
320 | ||
321 | /* seterrno_from_win_error: Given a Windows error code, set errno | |
322 | as appropriate. */ | |
323 | void __stdcall | |
324 | seterrno_from_win_error (const char *file, int line, DWORD code) | |
325 | { | |
326 | syscall_printf ("%s:%d windows error %d", file, line, code); | |
7cdcd90c CV |
327 | errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES); |
328 | } | |
329 | ||
86bf572e CV |
330 | int __stdcall |
331 | geterrno_from_nt_status (NTSTATUS status, int deferrno) | |
332 | { | |
333 | return geterrno_from_win_error (RtlNtStatusToDosError (status)); | |
334 | } | |
335 | ||
7cdcd90c CV |
336 | /* seterrno_from_nt_status: Given a NT status code, set errno |
337 | as appropriate. */ | |
338 | void __stdcall | |
339 | seterrno_from_nt_status (const char *file, int line, NTSTATUS status) | |
340 | { | |
341 | DWORD code = RtlNtStatusToDosError (status); | |
342 | SetLastError (code); | |
343 | syscall_printf ("%s:%d status %p -> windows error %d", | |
344 | file, line, status, code); | |
345 | errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES); | |
066ca06f CF |
346 | } |
347 | ||
348 | /* seterrno: Set `errno' based on GetLastError (). */ | |
349 | void __stdcall | |
350 | seterrno (const char *file, int line) | |
351 | { | |
352 | seterrno_from_win_error (file, line, GetLastError ()); | |
353 | } | |
354 | ||
355 | extern char *_user_strerror _PARAMS ((int)); | |
356 | ||
453185b1 CF |
357 | static char * |
358 | strerror_worker (int errnum) | |
359 | { | |
360 | char *res; | |
361 | if (errnum >= 0 && errnum < _sys_nerr) | |
362 | res = (char *) _sys_errlist [errnum]; | |
363 | else | |
364 | res = NULL; | |
365 | return res; | |
366 | } | |
1fd5e000 | 367 | |
3c9abad5 EB |
368 | /* strerror: convert from errno values to error strings. Newlib's |
369 | strerror_r returns "" for unknown values, so we override it to | |
370 | provide a nicer thread-safe result string and set errno. */ | |
1fd5e000 CF |
371 | extern "C" char * |
372 | strerror (int errnum) | |
373 | { | |
453185b1 CF |
374 | char *errstr = strerror_worker (errnum); |
375 | if (!errstr) | |
3c9abad5 EB |
376 | { |
377 | __small_sprintf (errstr = _my_tls.locals.strerror_buf, "Unknown error %u", | |
378 | (unsigned) errnum); | |
379 | errno = _impure_ptr->_errno = EINVAL; | |
380 | } | |
453185b1 CF |
381 | return errstr; |
382 | } | |
383 | ||
3c9abad5 EB |
384 | /* Newlib's <string.h> provides declarations for two strerror_r |
385 | variants, according to preprocessor feature macros. However, it | |
386 | returns "" instead of "Unknown error ...", so we override both | |
387 | versions. */ | |
388 | extern "C" char * | |
453185b1 CF |
389 | strerror_r (int errnum, char *buf, size_t n) |
390 | { | |
3c9abad5 EB |
391 | char *error = strerror (errnum); |
392 | if (strlen (error) >= n) | |
393 | return error; | |
394 | return strcpy (buf, error); | |
395 | } | |
396 | ||
397 | extern "C" int | |
398 | __xpg_strerror_r (int errnum, char *buf, size_t n) | |
399 | { | |
400 | if (!n) | |
453185b1 | 401 | return ERANGE; |
3c9abad5 EB |
402 | int result = 0; |
403 | char *error = strerror_worker (errnum); | |
b7351dcf | 404 | if (!error) |
3c9abad5 EB |
405 | { |
406 | __small_sprintf (error = _my_tls.locals.strerror_buf, "Unknown error %u", | |
407 | (unsigned) errnum); | |
408 | result = EINVAL; | |
409 | } | |
410 | if (strlen (error) >= n) | |
411 | { | |
412 | memcpy (buf, error, n - 1); | |
413 | buf[n - 1] = '\0'; | |
414 | return ERANGE; | |
415 | } | |
416 | strcpy (buf, error); | |
417 | return result; | |
1fd5e000 | 418 | } |