swrap: Add support for openat64()
authorAndreas Schneider <asn@samba.org>
Mon, 19 Jun 2023 14:23:50 +0000 (16:23 +0200)
committerAndreas Schneider <asn@samba.org>
Tue, 20 Jun 2023 11:38:46 +0000 (13:38 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
ConfigureChecks.cmake
config.h.cmake
src/socket_wrapper.c

index c99e2ae9edea9d8441e4dd44bcb2ff094cc7e232..daaee2b53a09a6bcfff525917a8db275067a2e6f 100644 (file)
@@ -70,6 +70,7 @@ check_function_exists(timerfd_create HAVE_TIMERFD_CREATE)
 check_function_exists(bindresvport HAVE_BINDRESVPORT)
 check_function_exists(accept4 HAVE_ACCEPT4)
 check_function_exists(open64 HAVE_OPEN64)
+check_function_exists(openat64 HAVE_OPENAT64)
 check_function_exists(fopen64 HAVE_FOPEN64)
 check_function_exists(getprogname HAVE_GETPROGNAME)
 check_function_exists(getexecname HAVE_GETEXECNAME)
index a637a34da5afbff5a8d04147db4fed09d2727701..399013e0fbc688102bf1ca7c1d2f11c0993ca199 100644 (file)
@@ -43,6 +43,7 @@
 #cmakedefine HAVE_BINDRESVPORT 1
 #cmakedefine HAVE_ACCEPT4 1
 #cmakedefine HAVE_OPEN64 1
+#cmakedefine HAVE_OPENAT64 1
 #cmakedefine HAVE_FOPEN64 1
 #cmakedefine HAVE_GETPROGNAME 1
 #cmakedefine HAVE_GETEXECNAME 1
index de2f73250595528a1f256b126c17144af6205ca3..dc07b53fcd0ce2c79b00cf4cfbb5dcc59d5ad6e0 100644 (file)
@@ -531,6 +531,9 @@ typedef int (*__libc_open)(const char *pathname, int flags, ...);
 #ifdef HAVE_OPEN64
 typedef int (*__libc_open64)(const char *pathname, int flags, ...);
 #endif /* HAVE_OPEN64 */
+#ifdef HAVE_OPENAT64
+typedef int (*__libc_openat64)(int dirfd, const char *pathname, int flags, ...);
+#endif /* HAVE_OPENAT64 */
 typedef int (*__libc_openat)(int dirfd, const char *path, int flags, ...);
 typedef int (*__libc_pipe)(int pipefd[2]);
 typedef int (*__libc_read)(int fd, void *buf, size_t count);
@@ -631,6 +634,9 @@ struct swrap_libc_symbols {
        SWRAP_SYMBOL_ENTRY(open);
 #ifdef HAVE_OPEN64
        SWRAP_SYMBOL_ENTRY(open64);
+#endif
+#ifdef HAVE_OPENAT64
+       SWRAP_SYMBOL_ENTRY(openat64);
 #endif
        SWRAP_SYMBOL_ENTRY(openat);
        SWRAP_SYMBOL_ENTRY(pipe);
@@ -1136,6 +1142,29 @@ static int libc_vopen64(const char *pathname, int flags, va_list ap)
 }
 #endif /* HAVE_OPEN64 */
 
+#ifdef HAVE_OPENAT64
+static int
+libc_vopenat64(int dirfd, const char *pathname, int flags, va_list ap)
+{
+       int mode = 0;
+       int fd;
+
+       swrap_bind_symbol_all();
+
+       swrap_inject_o_largefile(&flags);
+
+       if (flags & O_CREAT) {
+               mode = va_arg(ap, int);
+       }
+       fd = swrap.libc.symbols._libc_openat64.f(dirfd,
+                                                pathname,
+                                                flags,
+                                                (mode_t)mode);
+
+       return fd;
+}
+#endif /* HAVE_OPENAT64 */
+
 static int libc_vopenat(int dirfd, const char *path, int flags, va_list ap)
 {
        int mode = 0;
@@ -1441,6 +1470,9 @@ static void __swrap_bind_symbol_all_once(void)
        swrap_bind_symbol_libc(open);
 #ifdef HAVE_OPEN64
        swrap_bind_symbol_libc(open64);
+#endif
+#ifdef HAVE_OPENAT64
+       swrap_bind_symbol_libc(openat64);
 #endif
        swrap_bind_symbol_libc(openat);
        swrap_bind_symbol_libsocket(pipe);
@@ -4691,6 +4723,42 @@ int open64(const char *pathname, int flags, ...)
 }
 #endif /* HAVE_OPEN64 */
 
+/****************************************************************************
+ *   OPENAT64
+ ***************************************************************************/
+
+#ifdef HAVE_OPENAT64
+static int
+swrap_vopenat64(int dirfd, const char *pathname, int flags, va_list ap)
+{
+       int ret;
+
+       ret = libc_vopenat64(dirfd, pathname, flags, ap);
+       if (ret != -1) {
+               /*
+                * There are methods for closing descriptors (libc-internal code
+                * paths, direct syscalls) which close descriptors in ways that
+                * we can't intercept, so try to recover when we notice that
+                * that's happened
+                */
+               swrap_remove_stale(ret);
+       }
+       return ret;
+}
+
+int openat64(int dirfd, const char *pathname, int flags, ...)
+{
+       va_list ap;
+       int fd;
+
+       va_start(ap, flags);
+       fd = swrap_vopenat64(dirfd, pathname, flags, ap);
+       va_end(ap);
+
+       return fd;
+}
+#endif /* HAVE_OPENAT64 */
+
 /****************************************************************************
  *   OPENAT
  ***************************************************************************/