From 98d8782bfd1dfd1600e61412dcaab10c5dc0751a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 10:47:28 +0100 Subject: [PATCH 01/10] libredirect: use '_real' suffix for consistency 29 out of 33 redirected functions use '_real' suffix. Update the remaining 4 for consistent style. --- pkgs/by-name/li/libredirect/libredirect.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index fdbdcb6ebb86..2966867a5b16 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -300,26 +300,26 @@ WRAPPER_DEF(execv) WRAPPER(int, execvp)(const char * path, char * const argv[]) { - int (*_execvp) (const char *, char * const argv[]) = LOOKUP_REAL(execvp); + int (*execvp_real) (const char *, char * const argv[]) = LOOKUP_REAL(execvp); char buf[PATH_MAX]; - return _execvp(rewrite(path, buf), argv); + return execvp_real(rewrite(path, buf), argv); } WRAPPER_DEF(execvp) WRAPPER(int, execve)(const char * path, char * const argv[], char * const envp[]) { - int (*_execve) (const char *, char * const argv[], char * const envp[]) = LOOKUP_REAL(execve); + int (*execve_real) (const char *, char * const argv[], char * const envp[]) = LOOKUP_REAL(execve); char buf[PATH_MAX]; - return _execve(rewrite(path, buf), argv, envp); + return execve_real(rewrite(path, buf), argv, envp); } WRAPPER_DEF(execve) WRAPPER(DIR *, opendir)(const char * path) { char buf[PATH_MAX]; - DIR * (*_opendir) (const char*) = LOOKUP_REAL(opendir); + DIR * (*opendir_real) (const char*) = LOOKUP_REAL(opendir); - return _opendir(rewrite(path, buf)); + return opendir_real(rewrite(path, buf)); } WRAPPER_DEF(opendir) @@ -383,11 +383,11 @@ static void rewriteSystemCall(const char * command, char * buf) { WRAPPER(int, system)(const char *command) { - int (*_system) (const char*) = LOOKUP_REAL(system); + int (*system_real) (const char*) = LOOKUP_REAL(system); char newCommand[SYSTEM_CMD_MAX]; rewriteSystemCall(command, newCommand); - return _system(newCommand); + return system_real(newCommand); } WRAPPER_DEF(system) From d52bc27f96e13502a6b5b1fe3ed4a2f31ffe1038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 09:05:15 +0100 Subject: [PATCH 02/10] libredirect: add 'llistxattr' --- pkgs/by-name/li/libredirect/libredirect.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index 2966867a5b16..c3790026e240 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -323,6 +324,16 @@ WRAPPER(DIR *, opendir)(const char * path) } WRAPPER_DEF(opendir) +#if !defined(__APPLE__) +WRAPPER(ssize_t, llistxattr)(const char * path, char * list, size_t size) +{ + int (*llistxattr_real) (const char *, char *, size_t) = LOOKUP_REAL(llistxattr); + char buf[PATH_MAX]; + return llistxattr_real(rewrite(path, buf), list, size); +} +WRAPPER_DEF(llistxattr); +#endif + #define SYSTEM_CMD_MAX 512 static char * replace_substring(char * source, char * buf, char * replace_string, char * start_ptr, char * suffix_ptr) { From bb92c283dee35001050d7f52e303518173635b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 10:27:57 +0100 Subject: [PATCH 03/10] libredirect: add 'listxattr' --- pkgs/by-name/li/libredirect/libredirect.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index c3790026e240..fe5a916f5a69 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -324,6 +324,16 @@ WRAPPER(DIR *, opendir)(const char * path) } WRAPPER_DEF(opendir) +#if !defined(__APPLE__) +WRAPPER(ssize_t, listxattr)(const char * path, char * list, size_t size) +{ + int (*listxattr_real) (const char *, char *, size_t) = LOOKUP_REAL(listxattr); + char buf[PATH_MAX]; + return listxattr_real(rewrite(path, buf), list, size); +} +WRAPPER_DEF(listxattr); +#endif + #if !defined(__APPLE__) WRAPPER(ssize_t, llistxattr)(const char * path, char * list, size_t size) { From 21bd98adb3d28aac25d7885d96332a4d8eec9623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 09:05:35 +0100 Subject: [PATCH 04/10] libredirect: add 'chmod' --- pkgs/by-name/li/libredirect/libredirect.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index fe5a916f5a69..cc614f264823 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -420,6 +420,14 @@ WRAPPER(int, chdir)(const char *path) } WRAPPER_DEF(chdir); +WRAPPER(int, chmod)(const char * path, mode_t mode) +{ + int (*chmod_real) (const char *, mode_t) = LOOKUP_REAL(chmod); + char buf[PATH_MAX]; + return chmod_real(rewrite(path, buf), mode); +} +WRAPPER_DEF(chmod) + WRAPPER(int, mkdir)(const char *path, mode_t mode) { int (*mkdir_real) (const char *path, mode_t mode) = LOOKUP_REAL(mkdir); From f9be01f4c03636c1765e46a144498339c66baf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 09:11:52 +0100 Subject: [PATCH 05/10] libredirect: add 'remove' --- pkgs/by-name/li/libredirect/libredirect.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index cc614f264823..89ca4844dd67 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -460,6 +460,14 @@ WRAPPER(int, unlinkat)(int dirfd, const char *path, int flags) } WRAPPER_DEF(unlinkat) +WRAPPER(int, remove)(const char *path) +{ + int (*remove_real) (const char *path) = LOOKUP_REAL(remove); + char buf[PATH_MAX]; + return remove_real(rewrite(path, buf)); +} +WRAPPER_DEF(remove) + WRAPPER(int, rmdir)(const char *path) { int (*rmdir_real) (const char *path) = LOOKUP_REAL(rmdir); From e6a936c760e078f5f2e52673d6c4b36f1f6d945b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 10:23:17 +0100 Subject: [PATCH 06/10] libredirect: add 'bind' for AF_UNIX --- pkgs/by-name/li/libredirect/libredirect.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index 89ca4844dd67..15dd549a6bcb 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -1,11 +1,14 @@ #define _GNU_SOURCE #include #include +#include #include #include #include +#include #include #include +#include #include #include #include @@ -108,6 +111,25 @@ static int open_needs_mode(int flags) it contains only what we needed for programs in Nixpkgs. Just add more functions as needed. */ +WRAPPER(int, bind)(int socket, const struct sockaddr *addr, socklen_t addr_len) +{ + int (*bind_real) (int, const struct sockaddr *, socklen_t) = LOOKUP_REAL(bind); + char buf[PATH_MAX]; + const struct sockaddr *real_addr = addr; + if (addr->sa_family == AF_UNIX) { + struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; + const char *sun_path = rewrite(real_addr_un.sun_path, buf); + if (sun_path != real_addr_un.sun_path) { + strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); + real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; + real_addr = (struct sockaddr *)&real_addr_un; + addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; + } + } + return bind_real(socket, real_addr, addr_len); +} +WRAPPER_DEF(bind) + WRAPPER(int, open)(const char * path, int flags, ...) { int (*open_real) (const char *, int, ...) = LOOKUP_REAL(open); From 599a2f2fbe701b9ca2f12e9a97b77fc878e4cd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 19 Dec 2025 10:41:39 +0100 Subject: [PATCH 07/10] libredirect: add 'connect' for AF_UNIX --- pkgs/by-name/li/libredirect/libredirect.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index 15dd549a6bcb..bb88453216a6 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -130,6 +130,25 @@ WRAPPER(int, bind)(int socket, const struct sockaddr *addr, socklen_t addr_len) } WRAPPER_DEF(bind) +WRAPPER(int, connect)(int socket, const struct sockaddr *addr, socklen_t addr_len) +{ + int (*connect_real) (int, const struct sockaddr *, socklen_t) = LOOKUP_REAL(connect); + char buf[PATH_MAX]; + const struct sockaddr *real_addr = addr; + if (addr->sa_family == AF_UNIX) { + struct sockaddr_un real_addr_un = *(struct sockaddr_un *)addr; + const char *sun_path = rewrite(real_addr_un.sun_path, buf); + if (sun_path != real_addr_un.sun_path) { + strncpy(real_addr_un.sun_path, buf, sizeof(real_addr_un.sun_path) - 1); + real_addr_un.sun_path[sizeof(real_addr_un.sun_path) - 1] = '\0'; + real_addr = (struct sockaddr *)&real_addr_un; + addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(real_addr_un.sun_path) + 1; + } + } + return connect_real(socket, real_addr, addr_len); +} +WRAPPER_DEF(connect) + WRAPPER(int, open)(const char * path, int flags, ...) { int (*open_real) (const char *, int, ...) = LOOKUP_REAL(open); From ee4dd307bb6f366c87d4b408025ed909e55a168f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Thu, 17 Oct 2019 23:02:55 +0200 Subject: [PATCH 08/10] libredirect: add 'openat64' --- pkgs/by-name/li/libredirect/libredirect.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index bb88453216a6..011b5e6965c5 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -197,6 +197,24 @@ WRAPPER(int, openat)(int dirfd, const char * path, int flags, ...) } WRAPPER_DEF(openat) +// In musl libc, openat64 is simply a macro for openat +#if !defined(__APPLE__) && !defined(openat64) +WRAPPER(int, openat64)(int dirfd, const char * path, int flags, ...) +{ + int (*openat64_real) (int, const char *, int, ...) = LOOKUP_REAL(openat64); + mode_t mode = 0; + if (open_needs_mode(flags)) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + } + char buf[PATH_MAX]; + return openat64_real(dirfd, rewrite(path, buf), flags, mode); +} +WRAPPER_DEF(openat64) +#endif + WRAPPER(FILE *, fopen)(const char * path, const char * mode) { FILE * (*fopen_real) (const char *, const char *) = LOOKUP_REAL(fopen); From c63e9516f85a4edd63757707e9d657bd70c6e45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Tue, 20 Jan 2026 19:32:51 +0100 Subject: [PATCH 09/10] libredirect: add test for 'bind' --- pkgs/by-name/li/libredirect/package.nix | 2 +- pkgs/by-name/li/libredirect/test.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pkgs/by-name/li/libredirect/package.nix b/pkgs/by-name/li/libredirect/package.nix index 59e98b5eca65..2981d4d41a20 100644 --- a/pkgs/by-name/li/libredirect/package.nix +++ b/pkgs/by-name/li/libredirect/package.nix @@ -124,7 +124,7 @@ else installCheckPhase = '' ( source "$hook/nix-support/setup-hook" - NIX_REDIRECTS="/foo/bar/test=${coreutils}/bin/true:/bar/baz=$(mktemp -d)" ./test + NIX_REDIRECTS="/foo/bar/test=${coreutils}/bin/true:/bar/baz=$(mktemp -d):/run/sock=$PWD/test.sock" ./test ) ''; diff --git a/pkgs/by-name/li/libredirect/test.c b/pkgs/by-name/li/libredirect/test.c index 59a47d8a02ae..02233f0274e0 100644 --- a/pkgs/by-name/li/libredirect/test.c +++ b/pkgs/by-name/li/libredirect/test.c @@ -8,16 +8,32 @@ #include #include +#include #include #include +#include #include #define TESTDIR "/bar/baz" #define TESTPATH "/foo/bar/test" +#define TESTSOCK "/run/sock" #define SUBTEST "./test sub" extern char **environ; +void test_bind(void) { + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + assert(fd != -1); + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + .sun_path = TESTSOCK, + }; + unlink(TESTSOCK); + int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + assert(ret == 0); + close(fd); +} + void test_spawn(void) { pid_t pid; int ret; @@ -160,6 +176,7 @@ int main(int argc, char *argv[]) assert(mktemp(buf) == buf); assert_mktemp_path(TESTDIR "/temp", "", buf); + test_bind(); test_spawn(); test_system(); test_stat_with_null_path(); From 03f7190cab88f8fffbcf4fea3c1084484028736c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Tue, 20 Jan 2026 19:33:22 +0100 Subject: [PATCH 10/10] libredirect: add test for 'connect' --- pkgs/by-name/li/libredirect/test.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pkgs/by-name/li/libredirect/test.c b/pkgs/by-name/li/libredirect/test.c index 02233f0274e0..6d8d3494c2fe 100644 --- a/pkgs/by-name/li/libredirect/test.c +++ b/pkgs/by-name/li/libredirect/test.c @@ -34,6 +34,35 @@ void test_bind(void) { close(fd); } +void test_connect(void) { + // server + int server_fd = socket(AF_UNIX, SOCK_STREAM, 0); + assert(server_fd != -1); + struct sockaddr_un server_addr = { + .sun_family = AF_UNIX, + .sun_path = TESTSOCK, + }; + unlink(TESTSOCK); + int bind_ret = bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); + assert(bind_ret == 0); + int listen_ret = listen(server_fd, 5); + assert(listen_ret == 0); + + // client + int client_fd = socket(AF_UNIX, SOCK_STREAM, 0); + assert(client_fd != -1); + struct sockaddr_un client_addr = { + .sun_family = AF_UNIX, + .sun_path = TESTSOCK, + }; + int connect_ret = connect(client_fd, (struct sockaddr *)&client_addr, sizeof(client_addr)); + assert(connect_ret == 0); + + // clean up + close(server_fd); + close(client_fd); +} + void test_spawn(void) { pid_t pid; int ret; @@ -177,6 +206,7 @@ int main(int argc, char *argv[]) assert_mktemp_path(TESTDIR "/temp", "", buf); test_bind(); + test_connect(); test_spawn(); test_system(); test_stat_with_null_path();