#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);
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);
}
#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;
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);
}
#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
***************************************************************************/