diff options
| -rwxr-xr-x | tests/df/no-mtab-status.sh | 57 | ||||
| -rwxr-xr-x | tests/df/skip-duplicates.sh | 53 |
2 files changed, 84 insertions, 26 deletions
diff --git a/tests/df/no-mtab-status.sh b/tests/df/no-mtab-status.sh index 135462393..021e94991 100755 --- a/tests/df/no-mtab-status.sh +++ b/tests/df/no-mtab-status.sh @@ -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: diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh index c839f4e19..8521a9964 100755 --- a/tests/df/skip-duplicates.sh +++ b/tests/df/skip-duplicates.sh @@ -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; } |
