SWRAP_SYMBOL_ENTRY(connect);
SWRAP_SYMBOL_ENTRY(dup);
SWRAP_SYMBOL_ENTRY(dup2);
+ SWRAP_SYMBOL_ENTRY(fcntl);
#ifdef HAVE_FCNTL64
SWRAP_SYMBOL_ENTRY(fcntl64);
-#else
- SWRAP_SYMBOL_ENTRY(fcntl);
#endif
SWRAP_SYMBOL_ENTRY(fopen);
#ifdef HAVE_FOPEN64
arg = va_arg(ap, void *);
- /*
- * If fcntl64 exists then this is a system were fcntl is
- * renamed (including when building this file), and so we must
- * assume that the binary under test was built with
- * -D_FILE_OFFSET_BITS=64 and pass on to fcntl64.
- *
- * If we are wrong, then fcntl is unwrapped, but while that is
- * not ideal, is is also unlikely.
- *
- * In any case, it is always wrong to map fcntl64() to fcntl()
- * as this will cause a thunk from struct flock -> flock64
- * that the caller had already prepared for.
- */
+ rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
+
+ return rc;
+}
+
#ifdef HAVE_FCNTL64
+DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
+static int libc_vfcntl64(int fd, int cmd, va_list ap)
+{
+ void *arg;
+ int rc;
+
+ swrap_bind_symbol_all();
+
+ arg = va_arg(ap, void *);
+
rc = swrap.libc.symbols._libc_fcntl64.f(fd, cmd, arg);
-#else
- rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
-#endif
return rc;
}
+#endif
static int libc_getpeername(int sockfd,
struct sockaddr *addr,
swrap_bind_symbol_libsocket(connect);
swrap_bind_symbol_libc(dup);
swrap_bind_symbol_libc(dup2);
+ swrap_bind_symbol_libc(fcntl);
#ifdef HAVE_FCNTL64
swrap_bind_symbol_libc(fcntl64);
-#else
- swrap_bind_symbol_libc(fcntl);
#endif
swrap_bind_symbol_libc(fopen);
#ifdef HAVE_FOPEN64
return rc;
}
+/****************************
+ * FCNTL64
+ ***************************/
+
+#ifdef HAVE_FCNTL64
+static int swrap_vfcntl64(int fd, int cmd, va_list va)
+{
+ struct socket_info *si;
+ int rc, dup_fd, idx;
+
+ idx = find_socket_info_index(fd);
+ if (idx == -1) {
+ return libc_vfcntl64(fd, cmd, va);
+ }
+
+ si = swrap_get_socket_info(idx);
+
+ switch (cmd) {
+ case F_DUPFD:
+ dup_fd = libc_vfcntl64(fd, cmd, va);
+ if (dup_fd == -1) {
+ int saved_errno = errno;
+ errno = saved_errno;
+ return -1;
+ }
+
+ /* Make sure we don't have an entry for the fd */
+ swrap_remove_stale(dup_fd);
+
+ if ((size_t)dup_fd >= socket_fds_max) {
+ SWRAP_LOG(SWRAP_LOG_ERROR,
+ "The max socket index limit of %zu has been reached, "
+ "trying to add %d",
+ socket_fds_max,
+ dup_fd);
+ libc_close(dup_fd);
+ errno = EMFILE;
+ return -1;
+ }
+
+ SWRAP_LOCK_SI(si);
+
+ swrap_inc_refcount(si);
+
+ SWRAP_UNLOCK_SI(si);
+
+
+ set_socket_info_index(dup_fd, idx);
+
+ rc = dup_fd;
+ break;
+ default:
+ rc = libc_vfcntl64(fd, cmd, va);
+ break;
+ }
+
+ return rc;
+}
+
+int fcntl64(int fd, int cmd, ...)
+{
+ va_list va;
+ int rc;
+
+ va_start(va, cmd);
+
+ rc = swrap_vfcntl64(fd, cmd, va);
+
+ va_end(va);
+
+ return rc;
+}
+#endif
+
/****************************
* EVENTFD
***************************/