diff options
Diffstat (limited to 'pkgs/build-support/libredirect/libredirect.c')
-rw-r--r-- | pkgs/build-support/libredirect/libredirect.c | 133 |
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) |