OSDN Git Service

Support GCC-9.x gratuitous use of non-standard errno accessor API.
authorKeith Marshall <keith@users.osdn.me>
Fri, 17 Jan 2020 15:39:44 +0000 (15:39 +0000)
committerKeith Marshall <keith@users.osdn.me>
Fri, 17 Jan 2020 15:39:44 +0000 (15:39 +0000)
mingwrt/ChangeLog
mingwrt/include/errno.h
mingwrt/include/stdlib.h

index 86c8b1b..6e260e5 100644 (file)
@@ -1,3 +1,17 @@
+2020-01-17  Keith Marshall  <keith@users.osdn.me>
+
+       Support GCC-9.x gratuitous use of non-standard errno accessor API.
+
+       * include/stdlib.h (_get_errno, _set_errno): Declare prototypes;
+       implement them in-line, for legacy Windows versions which may lack
+       them, since GCC-9.x gratuitously and ill-advisedly requires them.
+       (__STDLIB_H_SOURCED__): Define, and selectively #include...
+
+       * include/errno.h: ...this, subject to criterion...
+       [__STDLIB_H_SOURCED__]: ...for exposure of only...
+       (errno): ...this public API declaration, and...
+       (EINVAL): ...this symbolic constant.
+
 2019-10-26  Keith Marshall  <keith@users.osdn.me>
 
        Fix MinGW-Issue #39757; avoid multiple vsnprintf() definitions.
index 8db04f3..2f96053 100644 (file)
@@ -6,7 +6,8 @@
  * $Id$
  *
  * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
- * Copyright (C) 1997-1999, 2001, 2003-2005, 2007, 2016, MinGW.org Project.
+ * Copyright (C) 1997-1999, 2001, 2003-2005, 2007, 2016, 2020,
+ *   MinGW.org Project.
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  *
  */
 #ifndef _ERRNO_H
+#pragma GCC system_header
+
+/* Although ISO-C requires inclusion of <errno.h>, for all content
+ * provided herein, Microsoft contravenes this by assuming that the
+ * "errno" variable is also declared in <stdlib.h>; allow partial
+ * inclusion, to support this anomaly...
+ */
+#ifndef __STDLIB_H_SOURCED__
+/* ...defining the _ERRNO_H multiple inclusion guard, only when
+ * <errno.h> is included explicitl, other than by <stdlib.h>
+ */
 #define _ERRNO_H
 
 /* All MinGW headers are expected to include <_mingw.h>; however...
 #include <_mingw.h>
 #endif
 
-/* Error code numbers.
- *
- * TODO: Can't be sure of some of these assignments, I guessed from the
- * names given by strerror and the defines in the Cygnus errno.h. A lot
- * of the names from the Cygnus errno.h are not represented, and a few
- * of the descriptions returned by strerror do not obviously match
- * their error naming.
+/* Error code numbers -- these are as documented at
+ * https://docs.microsoft.com/en-us/cpp/c-runtime-library/
+ * errno-doserrno-sys-errlist-and-sys-nerr?view=vs-2019
  */
 #define EPERM           1      /* Operation not permitted */
-#define ENOFILE         2      /* No such file or directory */
-#define ENOENT          2
+#define ENOENT          2      /* No such file or directory */
+#define ENOFILE         2      /* Microsoft legacy alias for ENOENT */
 #define ESRCH           3      /* No such process */
 #define EINTR           4      /* Interrupted function call */
 #define EIO             5      /* Input/output error */
 #define ENOMEM         12      /* Not enough space */
 #define EACCES         13      /* Permission denied */
 #define EFAULT         14      /* Bad address */
+
 /* 15 - Unknown Error */
-#define EBUSY          16      /* strerror reports "Resource device" */
+
+#define EBUSY          16      /* Device or resource busy */
 #define EEXIST         17      /* File exists */
-#define EXDEV          18      /* Improper link (cross-device link?) */
+#define EXDEV          18      /* Improper link (cross-device link) */
 #define ENODEV         19      /* No such device */
 #define ENOTDIR        20      /* Not a directory */
 #define EISDIR         21      /* Is a directory */
+
+#endif /* !__STDLIB_H_SOURCED__ */
+/* Microsoft's non-standard _get_errno() and _set_errno(), which are
+ * declared in <stdlib.h>, and for which we provide in-line support on
+ * legacy Windows versions, (also in <stdlib.h>), demand exposure of
+ * EINVAL within <stdlib.h>, (for legacy support), regardless of the
+ * state of _ERRNO_H.
+ */
 #define EINVAL         22      /* Invalid argument */
+
+#ifdef _ERRNO_H
+/* The remaining error codes are to be exposed only when <errno.h> has
+ * been included explicitly.
+ */
 #define ENFILE         23      /* Too many open files in system */
 #define EMFILE         24      /* Too many open files */
 #define ENOTTY         25      /* Inappropriate I/O control operation */
+
 /* 26 - Unknown Error */
+
 #define EFBIG          27      /* File too large */
 #define ENOSPC         28      /* No space left on device */
 #define ESPIPE         29      /* Invalid seek (seek on a pipe?) */
 #define EPIPE          32      /* Broken pipe */
 #define EDOM           33      /* Domain error (math functions) */
 #define ERANGE         34      /* Result too large (possibly too small) */
+
 /* 35 - Unknown Error */
-#define EDEADLOCK      36      /* Resource deadlock avoided (non-Cyg) */
-#define EDEADLK        36
+
+#define EDEADLK        36      /* Resource deadlock avoided (non-Cyg) */
+#define EDEADLOCK      36      /* Microsoft legacy alias for EDEADLK */
+
 /* 37 - Unknown Error */
+
 #define ENAMETOOLONG   38      /* Filename too long (91 in Cyg?) */
 #define ENOLCK         39      /* No locks available (46 in Cyg?) */
 #define ENOSYS         40      /* Function not implemented (88 in Cyg?) */
 #define ENOTEMPTY      41      /* Directory not empty (90 in Cyg?) */
 #define EILSEQ         42      /* Illegal byte sequence */
 
+#endif /* _ERRNO_H */
+#if ! (defined _ERRNO_H && defined _STDLIB_H)
+/* ISO-C requires that the standard errno feature is defined here, in
+ * <errno.h>, but Microsoft require it to also be defined in <stdlib.h>;
+ * we expose it for inclusion of both <errno.h> and <stdlib.h>, but we
+ * process it once only.
+ */
+#if ! defined RC_INVOKED && ! defined __ASSEMBLER__
 /* C language function prototype declarations are unnecessary, when
  * compiling resource files, and they actually represent syntactically
  * invalid statements, in preprocessed assembly language code.
  */
-#if ! defined RC_INVOKED && ! defined __ASSEMBLER__
-
 _BEGIN_C_DECLS
 
-/* Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see
- * stdlib.h.
+/* Definitions of errno.  For _doserrno, sys_nerr and * sys_errlist,
+ * see <stdlib.h>
  */
 #ifdef _UWIN
 #undef errno
@@ -116,8 +151,9 @@ _CRTIMP int* __cdecl __MINGW_NOTHROW _errno(void);
 _END_C_DECLS
 
 #endif /* ! RC_INVOKED && !__ASSEMBLY__ */
+#endif /* ! (_ERRNO_H && _STDLIB_H) */
 
-#if defined __PTW32_H && ! defined _PTW32_ERRNO_H
+#if defined _ERRNO_H && defined __PTW32_H && ! defined _PTW32_ERRNO_H
 /* As a courtesy to users of pthreads-win32, ensure that the appropriate
  * additional error codes, as defined by that package, are automatically
  * defined when <errno.h> is included AFTER any pthreads-win32 header; a
index 7a50d8a..bf7d72d 100644 (file)
@@ -7,7 +7,7 @@
  * $Id$
  *
  * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
- * Copyright (C) 1997-2009, 2011, 2014-2016, 2018, MinGW.org Project.
+ * Copyright (C) 1997-2009, 2011, 2014-2016, 2018, 2020, MinGW.org Project.
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -156,16 +156,43 @@ __MINGW_IMPORT char **__argv_dll;
 #endif  /*  __DECLSPEC_SUPPORTED */
 #endif  /* MB_CUR_MAX */
 
-/* FIXME: Nominally in <errno.h>, Microsoft likes to declare errno
- * in <stdlib.h> as well; we should factor this out.
+/* In MSVCR80.DLL, Microsoft introduced the following pair of errno
+ * accessor functions; they subsequently became available in MSVCRT.DLL
+ * from Vista onward.  Although they are not required by ISO-C, and they
+ * are more cumbersome to use, than referring to errno directly, the GCC
+ * developers have gratuitously chosen to assume, in GCC-9.x, that they
+ * are always supported on MS-Windows, regardless of Windows version.
+ * Logically, we might expect these to be declared in <errno.h>, but
+ * Microsoft's documentation insists that they are actually declared
+ * here; thus, to satisfy the GCC-9.x requirement, we will declare
+ * them unconditionally here ...
  */
-#ifdef _UWIN
-# undef errno
-  extern int errno;
-#else
-_CRTIMP __cdecl __MINGW_NOTHROW  int *_errno(void);
-# define errno  (*_errno())
+__cdecl __MINGW_NOTHROW  int _get_errno(int *);
+__cdecl __MINGW_NOTHROW  int _set_errno(int);
+
+/* ... then provide in-line implementations, (depending on gratuitous
+ * exposure of EINVAL, which strictly belongs in <errno.h> only, while
+ * also requiring declaring the ISO-C errno feature, which Microsoft
+ * documentation calls for both here, and in <errno.h>; we satisfy
+ * both of these requirements by selective <errno.h> inclusion).
+ */
+#define __STDLIB_H_SOURCED__ 1
+#include "errno.h"
+
+#if __MSVCRT_VERSION__ < __MSVCR80_DLL && _WIN32_WINNT < _WIN32_WINNT_VISTA
+/* These in-line implementations will support universal use of this API,
+ * even on legacy Windows versions pre-dating Vista, without requiring use
+ * of non-free MSVCRT80.DLL or later.
+ */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  int _get_errno( int *__val )
+{ return (__val == NULL) ? (errno = EINVAL) : 0 & (*__val = errno); }
+
+__CRT_ALIAS __cdecl __MINGW_NOTHROW  int _set_errno( int __val )
+{ errno = __val; return 0; }
+
 #endif
+#undef __STDLIB_H_SOURCED__
+
 _CRTIMP __cdecl __MINGW_NOTHROW  int *__doserrno(void);
 #define _doserrno  (*__doserrno())