From fcef9a175f810e7bfccbae9bf9e79b2b95da17ab Mon Sep 17 00:00:00 2001
From: Ben Gamari <ben@well-typed.com>
Date: Fri, 1 Apr 2022 13:28:22 -0400
Subject: [PATCH] configure: Make environ decl check more robust

Some platforms (e.g. Windows/clang64) declare `environ` in `<stdlib.h>`,
not `<unistd.h>`
---
 libraries/base/aclocal.m4       | 16 ++++++++++++++++
 libraries/base/configure.ac     |  2 ++
 libraries/base/include/HsBase.h |  4 ++--
 m4/fp_check_environ.m4          |  7 +++++--
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/libraries/base/aclocal.m4 b/libraries/base/aclocal.m4
index 3a028dda163..0336a092a8c 100644
--- a/libraries/base/aclocal.m4
+++ b/libraries/base/aclocal.m4
@@ -253,3 +253,19 @@ AS_IF([test "$ac_res" != no],
       [$6])dnl
 AS_VAR_POPDEF([ac_Search])dnl
 ])
+
+AC_DEFUN([FP_CHECK_ENVIRON],
+[
+  dnl--------------------------------------------------------------------
+  dnl * Check whether the libc headers provide a declaration for the
+  dnl environ symbol. If not then we will provide one in RtsSymbols.c.
+  dnl See #20512, #20577, #20861.
+  dnl
+  dnl N.B. Windows declares environ in <stdlib.h>; most others declare it
+  dnl in <unistd.h>.
+  dnl--------------------------------------------------------------------
+  AC_CHECK_DECLS([environ], [], [], [
+    #include <stdlib.h>
+    #include <unistd.h>
+  ])
+])
diff --git a/libraries/base/configure.ac b/libraries/base/configure.ac
index e0345494766..6fc96d92f4b 100644
--- a/libraries/base/configure.ac
+++ b/libraries/base/configure.ac
@@ -189,6 +189,8 @@ FP_CHECK_CONSTS([SIGINT], [
 dnl ** can we open files in binary mode?
 FP_CHECK_CONST([O_BINARY], [#include <fcntl.h>], [0])
 
+FP_CHECK_ENVIRON
+
 # We don't use iconv or libcharset on Windows, but if configure finds
 # them then it can cause problems. So we don't even try looking if
 # we are on Windows.
diff --git a/libraries/base/include/HsBase.h b/libraries/base/include/HsBase.h
index d5884473caf..243d9698ee8 100644
--- a/libraries/base/include/HsBase.h
+++ b/libraries/base/include/HsBase.h
@@ -552,9 +552,9 @@ INLINE int __hscore_open(char *file, int how, mode_t mode) {
 #include <crt_externs.h>
 INLINE char **__hscore_environ(void) { return *(_NSGetEnviron()); }
 #else
-/* ToDo: write a feature test that doesn't assume 'environ' to
- *    be in scope at link-time. */
+#if !HAVE_DECL_ENVIRON
 extern char** environ;
+#endif
 INLINE char **__hscore_environ(void) { return environ; }
 #endif
 
diff --git a/m4/fp_check_environ.m4 b/m4/fp_check_environ.m4
index 88bf0a52de2..f0daedc9c02 100644
--- a/m4/fp_check_environ.m4
+++ b/m4/fp_check_environ.m4
@@ -4,11 +4,14 @@ AC_DEFUN([FP_CHECK_ENVIRON],
 [
   dnl--------------------------------------------------------------------
   dnl * Check whether the libc headers provide a declaration for the
-  dnl environ symbol. If not then we will provide one in RtsSymbols.c. 
+  dnl environ symbol. If not then we will provide one in RtsSymbols.c.
   dnl See #20512, #20577, #20861.
+  dnl
+  dnl N.B. Windows declares environ in <stdlib.h>; most others declare it
+  dnl in <unistd.h>.
   dnl--------------------------------------------------------------------
   AC_CHECK_DECLS([environ], [], [], [
+    #include <stdlib.h>
     #include <unistd.h>
   ])
 ])
-
-- 
GitLab