diff --git a/pkgs/by-name/li/libredirect/libredirect.c b/pkgs/by-name/li/libredirect/libredirect.c index fdbdcb6ebb86..011b5e6965c5 100644 --- a/pkgs/by-name/li/libredirect/libredirect.c +++ b/pkgs/by-name/li/libredirect/libredirect.c @@ -1,11 +1,15 @@ #define _GNU_SOURCE #include #include +#include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -107,6 +111,44 @@ 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, 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); @@ -155,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); @@ -300,29 +360,49 @@ 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) +#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) +{ + 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) { @@ -383,11 +463,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) @@ -399,6 +479,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); @@ -431,6 +519,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); 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..6d8d3494c2fe 100644 --- a/pkgs/by-name/li/libredirect/test.c +++ b/pkgs/by-name/li/libredirect/test.c @@ -8,16 +8,61 @@ #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_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; @@ -160,6 +205,8 @@ int main(int argc, char *argv[]) assert(mktemp(buf) == buf); assert_mktemp_path(TESTDIR "/temp", "", buf); + test_bind(); + test_connect(); test_spawn(); test_system(); test_stat_with_null_path();