OSDN Git Service

Correct project name references in mingwrt source files.
[mingw/mingw-org-wsl.git] / mingwrt / include / stdlib.h
index 3b461fd..28762be 100644 (file)
@@ -7,7 +7,8 @@
  * $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
@@ -156,16 +157,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())
 
@@ -399,6 +427,20 @@ unsigned long wcstoul (const wchar_t *, wchar_t **, int);
 
 _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
@@ -481,10 +523,52 @@ _CRTIMP __cdecl __MINGW_NOTHROW  int mbtowc (wchar_t *, const char *, size_t);
 _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;
 
@@ -495,6 +579,96 @@ int __cdecl __MINGW_NOTHROW atexit (void (*)(void));
 _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
@@ -522,6 +696,22 @@ typedef struct { long quot, rem; } ldiv_t;
 _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.
@@ -531,8 +721,6 @@ _CRTIMP __cdecl __MINGW_NOTHROW  void _beep (unsigned int, unsigned int) __MINGW
 _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);
@@ -562,7 +750,6 @@ _CRTIMP __cdecl __MINGW_NOTHROW  wchar_t *_ltow (long, wchar_t *, int);
 _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 *);
@@ -746,9 +933,9 @@ __cdecl __MINGW_NOTHROW  wchar_t *ulltow (unsigned long long __n, wchar_t * __w,
  * 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 *);
@@ -796,7 +983,7 @@ __CRT_ALIAS __LIBIMPL__(( FUNCTION = mkstemp ))
 __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).
@@ -811,6 +998,24 @@ __cdecl __MINGW_NOTHROW  char *mkdtemp (char *__dirname_template)
 { 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