about summary refs log tree commit diff
path: root/pkgs/build-support/libredirect/libredirect.c
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support/libredirect/libredirect.c')
-rw-r--r--pkgs/build-support/libredirect/libredirect.c133
1 files changed, 128 insertions, 5 deletions
diff --git a/pkgs/build-support/libredirect/libredirect.c b/pkgs/build-support/libredirect/libredirect.c
index 7dac4684722f7..1222d2ee75c64 100644
--- a/pkgs/build-support/libredirect/libredirect.c
+++ b/pkgs/build-support/libredirect/libredirect.c
@@ -84,6 +84,13 @@ static const char * rewrite(const char * path, char * buf)
     return path;
 }
 
+static char * rewrite_non_const(char * path, char * buf)
+{
+    // as long as the argument `path` is non-const, we can consider discarding
+    // the const qualifier of the return value to be safe.
+    return (char *)rewrite(path, buf);
+}
+
 static int open_needs_mode(int flags)
 {
 #ifdef O_TMPFILE
@@ -112,7 +119,8 @@ WRAPPER(int, open)(const char * path, int flags, ...)
 }
 WRAPPER_DEF(open)
 
-#ifndef __APPLE__
+// In musl libc, open64 is simply a macro for open
+#if !defined(__APPLE__) && !defined(open64)
 WRAPPER(int, open64)(const char * path, int flags, ...)
 {
     int (*open64_real) (const char *, int, mode_t) = LOOKUP_REAL(open64);
@@ -152,7 +160,7 @@ WRAPPER(FILE *, fopen)(const char * path, const char * mode)
 }
 WRAPPER_DEF(fopen)
 
-#ifndef __APPLE__
+#ifdef __GLIBC__
 WRAPPER(FILE *, __nss_files_fopen)(const char * path)
 {
     FILE * (*__nss_files_fopen_real) (const char *) = LOOKUP_REAL(__nss_files_fopen);
@@ -162,7 +170,8 @@ WRAPPER(FILE *, __nss_files_fopen)(const char * path)
 WRAPPER_DEF(__nss_files_fopen)
 #endif
 
-#ifndef __APPLE__
+// In musl libc, fopen64 is simply a macro for fopen
+#if !defined(__APPLE__) && !defined(fopen64)
 WRAPPER(FILE *, fopen64)(const char * path, const char * mode)
 {
     FILE * (*fopen64_real) (const char *, const char *) = LOOKUP_REAL(fopen64);
@@ -172,7 +181,7 @@ WRAPPER(FILE *, fopen64)(const char * path, const char * mode)
 WRAPPER_DEF(fopen64)
 #endif
 
-#ifndef __APPLE__
+#ifdef __linux__
 WRAPPER(int, __xstat)(int ver, const char * path, struct stat * st)
 {
     int (*__xstat_real) (int ver, const char *, struct stat *) = LOOKUP_REAL(__xstat);
@@ -182,7 +191,7 @@ WRAPPER(int, __xstat)(int ver, const char * path, struct stat * st)
 WRAPPER_DEF(__xstat)
 #endif
 
-#ifndef __APPLE__
+#ifdef __linux__
 WRAPPER(int, __xstat64)(int ver, const char * path, struct stat64 * st)
 {
     int (*__xstat64_real) (int ver, const char *, struct stat64 *) = LOOKUP_REAL(__xstat64);
@@ -352,3 +361,117 @@ WRAPPER(int, mkdirat)(int dirfd, const char *path, mode_t mode)
     return mkdirat_real(dirfd, rewrite(path, buf), mode);
 }
 WRAPPER_DEF(mkdirat)
+
+WRAPPER(int, unlink)(const char *path)
+{
+    int (*unlink_real) (const char *path) = LOOKUP_REAL(unlink);
+    char buf[PATH_MAX];
+    return unlink_real(rewrite(path, buf));
+}
+WRAPPER_DEF(unlink)
+
+WRAPPER(int, unlinkat)(int dirfd, const char *path, int flags)
+{
+    int (*unlinkat_real) (int dirfd, const char *path, int flags) = LOOKUP_REAL(unlinkat);
+    char buf[PATH_MAX];
+    return unlinkat_real(dirfd, rewrite(path, buf), flags);
+}
+WRAPPER_DEF(unlinkat)
+
+WRAPPER(int, rmdir)(const char *path)
+{
+    int (*rmdir_real) (const char *path) = LOOKUP_REAL(rmdir);
+    char buf[PATH_MAX];
+    return rmdir_real(rewrite(path, buf));
+}
+WRAPPER_DEF(rmdir)
+
+static void copy_temp_wildcard(char * dest, char * src, int suffixlen) {
+    int dest_len = strnlen(dest, PATH_MAX);
+    int src_len = strnlen(src, PATH_MAX);
+    memcpy(dest + dest_len - (6 + suffixlen), src + src_len - (6 + suffixlen), 6);
+}
+
+WRAPPER(int, mkstemp)(char *template)
+{
+    int (*mkstemp_real) (char *template) = LOOKUP_REAL(mkstemp);
+    char buf[PATH_MAX];
+    char * rewritten = rewrite_non_const(template, buf);
+    int retval = mkstemp_real(rewritten);
+    if (retval >= 0 && rewritten != template) {
+        copy_temp_wildcard(template, rewritten, 0);
+    }
+    return retval;
+}
+WRAPPER_DEF(mkstemp)
+
+WRAPPER(int, mkostemp)(char *template, int flags)
+{
+    int (*mkostemp_real) (char *template, int flags) = LOOKUP_REAL(mkostemp);
+    char buf[PATH_MAX];
+    char * rewritten = rewrite_non_const(template, buf);
+    int retval = mkostemp_real(rewritten, flags);
+    if (retval >= 0 && rewritten != template) {
+        copy_temp_wildcard(template, rewritten, 0);
+    }
+    return retval;
+}
+WRAPPER_DEF(mkostemp)
+
+WRAPPER(int, mkstemps)(char *template, int suffixlen)
+{
+    int (*mkstemps_real) (char *template, int suffixlen) = LOOKUP_REAL(mkstemps);
+    char buf[PATH_MAX];
+    char * rewritten = rewrite_non_const(template, buf);
+    int retval = mkstemps_real(rewritten, suffixlen);
+    if (retval >= 0 && rewritten != template) {
+        copy_temp_wildcard(template, rewritten, suffixlen);
+    }
+    return retval;
+}
+WRAPPER_DEF(mkstemps)
+
+WRAPPER(int, mkostemps)(char *template, int suffixlen, int flags)
+{
+    int (*mkostemps_real) (char *template, int suffixlen, int flags) = LOOKUP_REAL(mkostemps);
+    char buf[PATH_MAX];
+    char * rewritten = rewrite_non_const(template, buf);
+    int retval = mkostemps_real(rewritten, suffixlen, flags);
+    if (retval >= 0 && rewritten != template) {
+        copy_temp_wildcard(template, rewritten, suffixlen);
+    }
+    return retval;
+}
+WRAPPER_DEF(mkostemps)
+
+WRAPPER(char *, mkdtemp)(char *template)
+{
+    char * (*mkdtemp_real) (char *template) = LOOKUP_REAL(mkdtemp);
+    char buf[PATH_MAX];
+    char * rewritten = rewrite_non_const(template, buf);
+    char * retval = mkdtemp_real(rewritten);
+    if (retval == NULL) {
+        return retval;
+    };
+    if (rewritten != template) {
+        copy_temp_wildcard(template, rewritten, 0);
+    }
+    return template;
+}
+WRAPPER_DEF(mkdtemp)
+
+WRAPPER(char *, mktemp)(char *template)
+{
+    char * (*mktemp_real) (char *template) = LOOKUP_REAL(mktemp);
+    char buf[PATH_MAX];
+    char * rewritten = rewrite_non_const(template, buf);
+    char * retval = mktemp_real(rewritten);
+    if (retval == NULL) {
+        return retval;
+    };
+    if (rewritten != template) {
+        copy_temp_wildcard(template, rewritten, 0);
+    }
+    return template;
+}
+WRAPPER_DEF(mktemp)