* $Id$
*
* Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
- * Copyright (C) 1997-2009, 2011, 2014-2016, MinGW.org Project.
+ * Copyright (C) 1997-2009, 2011, 2014-2016, 2018, 2020-2022,
+ * MinGW.OSDN Project
*
*
* Permission is hereby granted, free of charge, to any person obtaining a
#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())
_CRTIMP __cdecl __MINGW_NOTHROW double wcstod (const wchar_t *, wchar_t **);
+/* The following MinGW specific alternatives to wcstod(), which may
+ * offer more robust performance than the MSVCRT.DLL implementation,
+ * are provided in libmingwex.a; (the float and long double variants
+ * are simply aliases for the ISO-C99 equivalents which follow).
+ */
+__cdecl __MINGW_NOTHROW
+double __mingw_wcstod (const wchar_t *__restrict__, wchar_t **__restrict__);
+
+__cdecl __MINGW_NOTHROW
+float __mingw_wcstof (const wchar_t *__restrict__, wchar_t **__restrict__);
+
+__cdecl __MINGW_NOTHROW
+long double __mingw_wcstold (const wchar_t *__restrict__, wchar_t **__restrict__);
+
#ifdef _ISOC99_SOURCE
/* Variants on wcstod(), specified by ISO-C99; once again, MSVCRT.DLL
* doesn't have them, but we offer them in libmingwex.a
_CRTIMP __cdecl __MINGW_NOTHROW int rand (void);
_CRTIMP __cdecl __MINGW_NOTHROW void srand (unsigned int);
-_CRTIMP __cdecl __MINGW_NOTHROW void *calloc (size_t, size_t) __MINGW_ATTRIB_MALLOC;
-_CRTIMP __cdecl __MINGW_NOTHROW void *malloc (size_t) __MINGW_ATTRIB_MALLOC;
-_CRTIMP __cdecl __MINGW_NOTHROW void *realloc (void *, size_t);
-_CRTIMP __cdecl __MINGW_NOTHROW void free (void *);
+/* rand() is devoid of entropy, and is thus a mediocre pseudo-random number
+ * generator. Microsoft do offer a better quality (bogusly dubbed as a more
+ * secure) PRNG, in the guise of rand_s(), but it
+ *
+ * 1) must be explicitly enabled, by user defined feature test macro;
+ */
+#ifdef _CRT_RAND_S
+/*
+ * 2) is not supported on Win9x, nor any WinNT version prior to WinXP;
+ * 3) on WinXP, requires linking with non-free MSVCR80.DLL, or later;
+ * 4) is provided by MSVCRT.DLL, only from Vista onward.
+ */
+#if __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA
+
+_CRTIMP __cdecl __MINGW_NOTHROW int rand_s (unsigned int *);
+
+#endif /* Win-Vista || MSVCR80.DLL || later */
+#endif /* _CRT_RAND_S enabled */
+
+#if _XOPEN_SOURCE >= 500 || defined _BSD_SOURCE
+/* The POSIX.1-1990 Extended Systems Interface specification defines another
+ * alternative to rand(). While the statistical quality of this alternative
+ * cannot be assured, this implementation in libmingwex.a may be useful.
+ */
+__cdecl __MINGW_NOTHROW long __mingw_random (void);
+__cdecl __MINGW_NOTHROW void __mingw_srandom (unsigned int);
+__cdecl __MINGW_NOTHROW char *__mingw_initstate (unsigned int, char *, size_t);
+__cdecl __MINGW_NOTHROW char *__mingw_setstate (char *);
+
+__CRT_ALIAS __JMPSTUB__(( FUNCTION = random ))
+__cdecl __MINGW_NOTHROW long random (void){ return __mingw_random(); }
+
+__CRT_ALIAS __JMPSTUB__(( FUNCTION = srandom ))
+__cdecl __MINGW_NOTHROW void srandom (unsigned int __seed)
+{ __mingw_srandom (__seed); }
+
+__CRT_ALIAS __JMPSTUB__(( FUNCTION = initstate ))
+__cdecl __MINGW_NOTHROW char *initstate (unsigned int __seed, char *__buf, size_t __len)
+{ return __mingw_initstate (__seed, __buf, __len); }
+
+__CRT_ALIAS __JMPSTUB__(( FUNCTION = setstate ))
+__cdecl __MINGW_NOTHROW char *setstate (char *__buf)
+{ return __mingw_setstate (__buf); }
+
+#endif /* _XOPEN_SOURCE >= 500 || _BSD_SOURCE */
+
_CRTIMP __cdecl __MINGW_NOTHROW void abort (void) __MINGW_ATTRIB_NORETURN;
_CRTIMP __cdecl __MINGW_NOTHROW void exit (int) __MINGW_ATTRIB_NORETURN;
_CRTIMP __cdecl __MINGW_NOTHROW int system (const char *);
_CRTIMP __cdecl __MINGW_NOTHROW char *getenv (const char *);
+#ifndef __STRICT_ANSI__
+/* For GNU compatibility, in addition to the standard memory allocation
+ * functions (declared below), we also include the non-standard alloca()
+ * API declarations here, in accordance with GNU convention.
+ */
+# include "alloca.h"
+#endif /* !__STRICT_ANSI__ */
+
+_CRTIMP __cdecl __MINGW_NOTHROW void *calloc (size_t, size_t) __MINGW_ATTRIB_MALLOC;
+_CRTIMP __cdecl __MINGW_NOTHROW void *malloc (size_t) __MINGW_ATTRIB_MALLOC;
+_CRTIMP __cdecl __MINGW_NOTHROW void *realloc (void *, size_t);
+_CRTIMP __cdecl __MINGW_NOTHROW void free (void *);
+
+/* The following pair of MinGW alternatives to realloc() and free() are
+ * always suitable as substitutes for their MSVCRT.DLL counterparts; the
+ * advantage of such substitutions is that these alternatives are able to
+ * operate on heap memory which has been allocated by the MinGW aligned
+ * memory allocation API functions, (but NOT the corresponding Microsoft
+ * functions), in addition to memory allocated by malloc() or calloc().
+ */
+__cdecl __MINGW_NOTHROW void *__mingw_realloc (void *, size_t);
+__cdecl __MINGW_NOTHROW void __mingw_free (void *);
+
+/* Since MinGW's __mingw_free() and __mingw_realloc() are able to
+ * operate transparently on pointers returned by any of Microsoft's
+ * heap allocators, except their over-aligned variants, just as they
+ * operate on pointers returned by MinGW's over-aligned allocators,
+ * and all of ISO-C11, C++17, and POSIX.1 require this capability,
+ * always prefer these replacements for free() and realloc().
+ */
+__JMPSTUB__(( LIB = memalign, FUNCTION = free ))
+__CRT_ALIAS __cdecl __MINGW_NOTHROW void free (void *__ptr)
+{ __mingw_free (__ptr); }
+
+__JMPSTUB__(( LIB = memalign, FUNCTION = realloc ))
+__CRT_ALIAS __cdecl __MINGW_NOTHROW void *realloc (void *__ptr, size_t __want)
+{ return __mingw_realloc (__ptr, __want); }
+
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201703L
+/* ISO-C99 adds support for over-aligned heap memory allocation, by use
+ * of the aligned_alloc() function, (which was subsequently incorporated
+ * into ISO-C++17 as std::aligned_alloc()); we may conveniently support
+ * this by use of MinGW's __mingw_aligned_offset_malloc(), which is
+ * nominally declared in <malloc.h>, and reproduced here:
+ */
+__cdecl __MINGW_NOTHROW __MINGW_ATTRIB_MALLOC
+void *__mingw_aligned_offset_malloc (size_t, size_t, size_t);
+
+__CRT_ALIAS __LIBIMPL__(( LIB = memalign, FUNCTION = aligned_alloc ))
+
+__cdecl __MINGW_NOTHROW __MINGW_ATTRIB_MALLOC
+void *aligned_alloc (size_t __alignment, size_t __want)
+{ return __mingw_aligned_offset_malloc( __want, __alignment, (size_t)(0) ); }
+
+/* For the ISO-C++17 case, we need to ensure that the feature test
+ * macro _GLIBCXX_HAVE_ALIGNED_ALLOC is defined, with non-zero value;
+ * (it is interpreted in <cstdlib>, but only for C++17 and later).
+ */
+#undef _GLIBCXX_HAVE_ALIGNED_ALLOC
+#define _GLIBCXX_HAVE_ALIGNED_ALLOC 1
+#endif /* ISO-C11 || ISO-C++17 */
+
+#if _POSIX_C_SOURCE >= 200112L
+/* POSIX.1-2001 supports an (earlier) alternative to the preceding
+ * ISO-C11 aligned_alloc(), namely posix_memalign(). Once again, we
+ * may conveniently use __mingw_aligned_offset_malloc() to implement
+ * this, (duplicating its prototype once again, just in case we did
+ * not implement the ISO-C11 function).
+ */
+__cdecl __MINGW_NOTHROW __MINGW_ATTRIB_MALLOC
+void *__mingw_aligned_offset_malloc (size_t, size_t, size_t);
+
+__CRT_ALIAS __LIBIMPL__(( LIB = memalign, FUNCTION = memalign ))
+
+/* posix_memalign() differs semantically from aligned_alloc(), in
+ * returning a status code, which is zero on success, or the value
+ * of errno on failure, with the allocated memory pointer returned
+ * via a reference parameter. Normally, the reference to errno as
+ * a possible return value would preclude inline implementation of
+ * this function, but since Microsoft gratuitously defines errno
+ * here, in <stdlib.h>, as well as in <errno.h>, this is okay.
+ */
+__cdecl __MINGW_NOTHROW
+int posix_memalign (void **__p, size_t __alignment, size_t __want)
+{ if( sizeof (void *) > __alignment ) __alignment = (sizeof (void *) << 1) - 1;
+ *__p = __mingw_aligned_offset_malloc (__want, __alignment, (size_t)(0));
+ return (*__p == NULL) ? errno : 0;
+}
+#endif /* POSIX.1-2001 */
+
/* bsearch() and qsort() are declared both here, in <stdlib.h>, and in
* non-ANSI header <search.h>; we reproduce these declarations in both,
* with no attempt to guard them, so the compiler may verify that they
_CRTIMP __cdecl __MINGW_NOTHROW div_t div (int, int) __MINGW_ATTRIB_CONST;
_CRTIMP __cdecl __MINGW_NOTHROW ldiv_t ldiv (long, long) __MINGW_ATTRIB_CONST;
+#if !defined __STRICT_ANSI__ || (defined _ISOC99_SOURCE && !defined __NO_INLINE__)
+/* Although not nominally valid in "__STRICT_ANSI__" mode, when compiling C99
+ * source, we use Microsoft's _exit() function to facilitate our provision of
+ * an inline implementation of ISO-C99's _Exit() function.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW void _exit (int) __MINGW_ATTRIB_NORETURN;
+
+#ifdef __MSVCRT__
+/* Similarly, we use Microsoft's MSVCRT.DLL specific _atoi64() function,
+ * to facilitate an inline implementation of ISO-C99's atoll() function.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW __int64 _atoi64 (const char *);
+
+#endif /* __MSVCRT__ */
+#endif /* !__STRICT_ANSI__ || (_ISOC99_SOURCE && !__NO_INLINE__) */
+
#if !defined (__STRICT_ANSI__)
/* NOTE: Officially the three following functions are obsolete. The Win32 API
* functions SetErrorMode, Beep and Sleep are their replacements.
_CRTIMP __cdecl __MINGW_NOTHROW void _seterrormode (int) __MINGW_ATTRIB_DEPRECATED;
_CRTIMP __cdecl __MINGW_NOTHROW void _sleep (unsigned long) __MINGW_ATTRIB_DEPRECATED;
-_CRTIMP __cdecl __MINGW_NOTHROW void _exit (int) __MINGW_ATTRIB_NORETURN;
-
/* _onexit is a Microsoft extension. Use atexit for portability. */
/* Note: This is in startup code, not imported directly from dll */
typedef int (* _onexit_t)(void);
_CRTIMP __cdecl __MINGW_NOTHROW wchar_t *_ultow (unsigned long, wchar_t *, int);
#ifdef __MSVCRT__
-_CRTIMP __cdecl __MINGW_NOTHROW __int64 _atoi64 (const char *);
_CRTIMP __cdecl __MINGW_NOTHROW char* _i64toa (__int64, char *, int);
_CRTIMP __cdecl __MINGW_NOTHROW char* _ui64toa (unsigned __int64, char *, int);
_CRTIMP __cdecl __MINGW_NOTHROW __int64 _wtoi64 (const wchar_t *);
* the basis of appropriate POSIX or BSD specific feature tests...
*
* mkstemp(3) function support; added per feature request #2003.
- * POSIX wants _XOPEN_SOURCE >= 500, (implying _POSIX_C_SOURCE >= 200112L).
+ * POSIX wants _XOPEN_SOURCE >= 500, (implying _POSIX_C_SOURCE >= 199506L).
*/
-#if _POSIX_C_SOURCE >= 200112L
+#if _POSIX_C_SOURCE >= 199506L
__cdecl __MINGW_NOTHROW int mkstemp (char *);
__cdecl __MINGW_NOTHROW int __mingw_mkstemp (int, char *);
__cdecl __MINGW_NOTHROW int mkstemp (char *__filename_template)
{ return __mingw_mkstemp( _MKSTEMP_INVOKE, __filename_template ); }
-#endif /* _POSIX_C_SOURCE >= 200112L (for mkstemp()) */
+#endif /* _POSIX_C_SOURCE >= 199506L (for mkstemp()) */
/* mkdtemp(3) function support: added as adjunct to feature request #2003.
* POSIX wants _XOPEN_SOURCE >= 700, (implying _POSIX_C_SOURCE >= 200809L).
{ return __mingw_mkdtemp( __dirname_template ); }
#endif /* _POSIX_C_SOURCE >= 200809L (for mkdtemp()) */
+
+#if _POSIX_C_SOURCE >= 200112L
+/* setenv() and unsetenv() are also available, from POSIX.1-2001 onwards.
+ */
+__cdecl __MINGW_NOTHROW int setenv( const char *, const char *, int );
+__cdecl __MINGW_NOTHROW int unsetenv( const char * );
+
+__cdecl __MINGW_NOTHROW int __mingw_setenv( const char *, const char *, int );
+
+__CRT_ALIAS __JMPSTUB__(( FUNCTION = setenv ))
+__cdecl __MINGW_NOTHROW int setenv( const char *__n, const char *__v, int __f )
+{ return __mingw_setenv( __n, __v, __f ); }
+
+__CRT_ALIAS __LIBIMPL__(( FUNCTION = unsetenv ))
+__cdecl __MINGW_NOTHROW int unsetenv( const char *__name )
+{ return __mingw_setenv( __name, NULL, 1 ); }
+
+#endif /* _POSIX_C_SOURCE >= 200112L (for setenv()) */
#endif /* _STDLIB_H */
_END_C_DECLS