bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] tests: fix test-execute with GNU make jobserver


From: Bruno Haible
Subject: Re: [PATCH] tests: fix test-execute with GNU make jobserver
Date: Thu, 08 Apr 2021 01:44:35 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-206-generic; KDE/5.18.0; x86_64; ; )

Hi Dmitry,

> Yes, it is reliable as it mirrors
>       for (fd = 0; fd < 20; fd++)
> piece of code in tests/test-execute-child.c file.

Ah, I had missed that. Thanks.

> there could
> be other external sources of inherited descriptors, so the test should
> rather be robust and make sure these external sources do not affect the
> test.

Yes, KDE/plasma and NetBSD are such external sources of inherited descriptors.

> I'd choose a simple close() rather than a bit more complex cloexec if
> tests/test-execute-child.c did not contain this uncommented hunk:
>         for (fd = 0; fd < 20; fd++)
>           #ifdef __NetBSD__
>           if (fd != 3)
>           #endif
> 
> If for some reason __NetBSD__ is allowed to have descriptor #3 inherited,
> then it shouldn't be closed in tests/test-execute-main.c either.

That was just my first attempt at working around the issue. It occurred
first on NetBSD.

> > 4) How about other environments? I saw 'test-execute.sh' also fail in
> > some recent Linux distro with KDE desktop. Apparently 'plasma' is passing
> > one or two open file descriptors to all children (that is, to all processes
> > running in this desktop environment). Do you think this is worth reporting?
> 
> If it isn't documented, then I'd say it's a bug, please report it.

Will do.

> > If so, Gnulib should probably provide a substitute close_range(), and
> > test-execute-main.c should better call this function, rather than rolling
> > its own loop.
> 
> Yes, I think it makes sense to provide this API in gnulib, although it
> won't be able to address all issues the syscall is intended to address.

I now read from [1] comment 23:
  "The close_range seems a sensible addition to added as a syscall wrapper
   for Linux, without any extra fallback, and returning ENOSYS on older
   kernel (as for copy_file_range)."
So, Gnulib would have to provide a function that invokes close_range AND
has fallback code. (That is general philosophy of Gnulib: provide
easily usable functions, rather than very low-level bricks that require
extensive manpage consultation before use.)

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=10353

I'm applying this fix:


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.

diff --git a/modules/execute-tests b/modules/execute-tests
index 422c1ab..c942130 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 c3a1190..dbaae1e 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 39e24af..944dcd1 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:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]