|| 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>
#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, ...);
}
}
- 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"))
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)
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
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:
|| 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>
#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, ...);
}
}
- 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"))
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)
/* Prove that LD_PRELOAD works. */
if (!done)
{
- fclose (fopen ("x", "w"));
+ fclose (fopen_func ("x", "w"));
++done;
}