]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tests: avoid skipping of LD_PRELOAD based df tests
authorBernhard Voelker <mail@bernhard-voelker.de>
Sat, 1 Nov 2025 21:27:59 +0000 (22:27 +0100)
committerBernhard Voelker <mail@bernhard-voelker.de>
Tue, 4 Nov 2025 10:33:35 +0000 (11:33 +0100)
It was seen that gnulib's read_file_system_list may use fopen instead
of open.  Adjust the df(1) tests to replace both library functions.

* tests/df/no-mtab-status.sh: Change the shared library code invoked
via LD_PRELOAD to override both fopen and open.  While at it, perform
varargs processing only when path is not "/proc/self/mountinfo".
* tests/df/skip-duplicates.sh: Likewise.

tests/df/no-mtab-status.sh
tests/df/skip-duplicates.sh

index 135462393d76742550ba06885d75868064c647a0..021e9499168efe59adc7a0fa23d6d9d8b0d2ce3f 100755 (executable)
@@ -28,8 +28,8 @@ grep '^#define HAVE_GETMNTENT 1' $CONFIG_HEADER > /dev/null \
       || skip_ "getmntent is not used on this system"
 
 # Simulate "mtab" failure.
-# Replace gnulib streq as that is not available here.
-sed 's/streq/0==str''cmp/' > k.c <<EOF || framework_failure_
+# Replace gnulib streq and C23 nullptr as that are not available here.
+sed 's/streq/0==str''cmp/; s/nullptr/NU''LL/' > k.c <<EOF || framework_failure_
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
@@ -40,6 +40,35 @@ sed 's/streq/0==str''cmp/' > k.c <<EOF || framework_failure_
 #include <stdarg.h>
 #include <dlfcn.h>
 
+static FILE* (*fopen_func)(const char *, const char *);
+
+FILE* fopen(const char *path, const char *mode)
+{
+
+  /* get reference to original (libc provided) fopen */
+  if (!fopen_func)
+    {
+      fopen_func = (FILE*(*)(const char *, const char *))
+                   dlsym(RTLD_NEXT, "fopen");
+      if (!fopen_func)
+        {
+          fprintf (stderr, "Failed to find fopen()\n");
+          errno = ESRCH;
+          return nullptr;
+        }
+    }
+
+  /* Returning ENOENT here will get read_file_system_list()
+     to fall back to using getmntent() below.  */
+  if (streq (path, "/proc/self/mountinfo"))
+    {
+      errno = ENOENT;
+      return nullptr;
+    }
+
+  return fopen_func(path, mode);
+}
+
 int open(const char *path, int flags, ...)
 {
   static int (*open_func)(const char *, int, ...);
@@ -57,13 +86,6 @@ int open(const char *path, int flags, ...)
         }
     }
 
-  va_list ap;
-  va_start (ap, flags);
-  mode_t mode = (sizeof (mode_t) < sizeof (int)
-                 ? va_arg (ap, int)
-                 : va_arg (ap, mode_t));
-  va_end (ap);
-
   /* Returning ENOENT here will get read_file_system_list()
      to fall back to using getmntent() below.  */
   if (streq (path, "/proc/self/mountinfo"))
@@ -71,8 +93,15 @@ int open(const char *path, int flags, ...)
       errno = ENOENT;
       return -1;
     }
-  else
-    return open_func(path, flags, mode);
+
+  va_list ap;
+  va_start (ap, flags);
+  mode_t mode = (sizeof (mode_t) < sizeof (int)
+                 ? va_arg (ap, int)
+                 : va_arg (ap, mode_t));
+  va_end (ap);
+
+  return open_func(path, flags, mode);
 }
 
 struct mntent *getmntent (FILE *fp)
@@ -81,12 +110,12 @@ struct mntent *getmntent (FILE *fp)
   static int done = 0;
   if (!done)
     {
-      fclose (fopen ("x", "w"));
+      fclose (fopen_func ("x", "w"));
       ++done;
     }
   /* Now simulate the failure. */
   errno = ENOENT;
-  return NULL;
+  return nullptr;
 }
 EOF
 
@@ -99,7 +128,7 @@ cleanup_() { unset LD_PRELOAD; }
 export LD_PRELOAD=$LD_PRELOAD:./k.so
 
 # Test if LD_PRELOAD works:
-df 2>/dev/null
+df
 test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?"
 
 # These tests are supposed to succeed:
index c839f4e191a8fcf59b57cf942b252fcb8ddd1fa9..8521a99644db0ec7ad953262b5e7494acc67af44 100755 (executable)
@@ -38,8 +38,8 @@ grep '^#define HAVE_GETMNTENT 1' $CONFIG_HEADER > /dev/null \
       || skip_ "getmntent is not used on this system"
 
 # Simulate an mtab file to test various cases.
-# Replace gnulib streq as that is not available here.
-sed 's/streq/0==str''cmp/' > k.c <<EOF || framework_failure_
+# Replace gnulib streq and C23 nullptr as that are not available here.
+sed 's/streq/0==str''cmp/; s/nullptr/NU''LL/' > k.c <<EOF || framework_failure_
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
@@ -50,6 +50,35 @@ sed 's/streq/0==str''cmp/' > k.c <<EOF || framework_failure_
 #include <stdarg.h>
 #include <dlfcn.h>
 
+static FILE* (*fopen_func)(const char *, const char *);
+
+FILE* fopen(const char *path, const char *mode)
+{
+
+  /* get reference to original (libc provided) fopen */
+  if (!fopen_func)
+    {
+      fopen_func = (FILE*(*)(const char *, const char *))
+                   dlsym(RTLD_NEXT, "fopen");
+      if (!fopen_func)
+        {
+          fprintf (stderr, "Failed to find fopen()\n");
+          errno = ESRCH;
+          return nullptr;
+        }
+    }
+
+  /* Returning ENOENT here will get read_file_system_list()
+     to fall back to using getmntent() below.  */
+  if (streq (path, "/proc/self/mountinfo"))
+    {
+      errno = ENOENT;
+      return nullptr;
+    }
+
+  return fopen_func(path, mode);
+}
+
 int open(const char *path, int flags, ...)
 {
   static int (*open_func)(const char *, int, ...);
@@ -67,13 +96,6 @@ int open(const char *path, int flags, ...)
         }
     }
 
-  va_list ap;
-  va_start (ap, flags);
-  mode_t mode = (sizeof (mode_t) < sizeof (int)
-                 ? va_arg (ap, int)
-                 : va_arg (ap, mode_t));
-  va_end (ap);
-
   /* Returning ENOENT here will get read_file_system_list()
      to fall back to using getmntent() below.  */
   if (streq (path, "/proc/self/mountinfo"))
@@ -81,8 +103,15 @@ int open(const char *path, int flags, ...)
       errno = ENOENT;
       return -1;
     }
-  else
-    return open_func(path, flags, mode);
+
+  va_list ap;
+  va_start (ap, flags);
+  mode_t mode = (sizeof (mode_t) < sizeof (int)
+                 ? va_arg (ap, int)
+                 : va_arg (ap, mode_t));
+  va_end (ap);
+
+  return open_func(path, flags, mode);
 }
 
 struct mntent *getmntent (FILE *fp)
@@ -94,7 +123,7 @@ struct mntent *getmntent (FILE *fp)
   /* Prove that LD_PRELOAD works. */
   if (!done)
     {
-      fclose (fopen ("x", "w"));
+      fclose (fopen_func ("x", "w"));
       ++done;
     }