From 2a7948aad478bcdcd2472b380054f84e7360ec10 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Thu, 8 Apr 2021 01:37:05 +0200
Subject: [PATCH] execute tests: Avoid test failure in certain environments.

Reported by Dmitry V. Levin <ldv@altlinux.org> in
<https://lists.gnu.org/archive/html/bug-gnulib/2021-04/msg00082.html>.

* tests/test-execute-main.c (main): Close file descriptors 3..19.
* tests/test-execute-child.c (main): Remove NetBSD workaround.
* modules/execute-tests (configure.ac): Test for close_range function.
---
 ChangeLog                  |  9 +++++++++
 modules/execute-tests      |  2 ++
 tests/test-execute-child.c | 13 +++++--------
 tests/test-execute-main.c  | 25 +++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index caca85d634..8d8725be2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2021-04-07  Bruno Haible  <bruno@clisp.org>
+
+	execute tests: Avoid test failure in certain environments.
+	Reported by Dmitry V. Levin <ldv@altlinux.org> in
+	<https://lists.gnu.org/archive/html/bug-gnulib/2021-04/msg00082.html>.
+	* tests/test-execute-main.c (main): Close file descriptors 3..19.
+	* tests/test-execute-child.c (main): Remove NetBSD workaround.
+	* modules/execute-tests (configure.ac): Test for close_range function.
+
 2021-04-07  Paul Eggert  <eggert@cs.ucla.edu>
 
 	xalloc: simplify integer overflow test
diff --git a/modules/execute-tests b/modules/execute-tests
index 422c1abe72..c9421302bf 100644
--- a/modules/execute-tests
+++ b/modules/execute-tests
@@ -18,6 +18,8 @@ stdint
 unistd
 
 configure.ac:
+dnl Test for Linux system call close_range(), declared in <unistd.h>.
+AC_CHECK_FUNCS([close_range])
 
 Makefile.am:
 TESTS += test-execute.sh
diff --git a/tests/test-execute-child.c b/tests/test-execute-child.c
index c3a1190f51..dbaae1e962 100644
--- a/tests/test-execute-child.c
+++ b/tests/test-execute-child.c
@@ -171,14 +171,11 @@ main (int argc, char *argv[])
         char *p = buf;
         int fd;
         for (fd = 0; fd < 20; fd++)
-          #ifdef __NetBSD__
-          if (fd != 3)
-          #endif
-            if (is_open (fd))
-              {
-                sprintf (p, "%d ", fd);
-                p += strlen (p);
-              }
+          if (is_open (fd))
+            {
+              sprintf (p, "%d ", fd);
+              p += strlen (p);
+            }
         const char *expected = (test < 16 ? "0 1 2 10 " : "0 1 2 ");
         if (strcmp (buf, expected) == 0)
           return 0;
diff --git a/tests/test-execute-main.c b/tests/test-execute-main.c
index 39e24af125..944dcd1ee2 100644
--- a/tests/test-execute-main.c
+++ b/tests/test-execute-main.c
@@ -58,6 +58,31 @@ main (int argc, char *argv[])
   char *prog_path = argv[1];
   const char *progname = "test-execute-child";
   int test = atoi (argv[2]);
+
+  switch (test)
+    {
+    case 14:
+    case 15:
+    case 16:
+      /* Close file descriptors that have been inherited from the parent
+         process and that would cause failures in test-execute-child.c.
+         Such file descriptors have been seen:
+           - with GNU make, when invoked as 'make -j N' with j > 1,
+           - in some versions of the KDE desktop environment,
+           - on NetBSD.
+       */
+      #if HAVE_CLOSE_RANGE
+      if (close_range (3, 20 - 1, 0) < 0)
+      #endif
+        {
+          int fd;
+          for (fd = 3; fd < 20; fd++)
+            close (fd);
+        }
+    default:
+      break;
+    }
+
   switch (test)
     {
     case 0:
-- 
2.39.5