OSDN Git Service

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