]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/errno.cc
* cygerrno.h (geterrno_from_nt_status): Declare.
[newlib-cygwin.git] / winsup / cygwin / errno.cc
CommitLineData
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
6This file is part of Cygwin.
7
8This software is a copyrighted work licensed under the terms of the
9Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10details. */
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
30static 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 154extern "C" {
c4ca0e80 155const 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 303int NO_COPY_INIT _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]);
0476bae5 304};
1fd5e000 305
066ca06f
CF
306int __stdcall
307geterrno_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. */
323void __stdcall
324seterrno_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
330int __stdcall
331geterrno_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. */
338void __stdcall
339seterrno_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 (). */
349void __stdcall
350seterrno (const char *file, int line)
351{
352 seterrno_from_win_error (file, line, GetLastError ());
353}
354
355extern char *_user_strerror _PARAMS ((int));
356
453185b1
CF
357static char *
358strerror_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
371extern "C" char *
372strerror (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. */
388extern "C" char *
453185b1
CF
389strerror_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
397extern "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}
This page took 0.376866 seconds and 5 git commands to generate.