Add fix for incorrect mapping of fcntl64() -> fcntl(), causing locking failures
[socket_wrapper.git] / src / socket_wrapper.c
index bf4a976eaee7069ab4bade1c650ca3969d5bfd56..de2f73250595528a1f256b126c17144af6205ca3 100644 (file)
@@ -611,7 +611,11 @@ struct swrap_libc_symbols {
        SWRAP_SYMBOL_ENTRY(connect);
        SWRAP_SYMBOL_ENTRY(dup);
        SWRAP_SYMBOL_ENTRY(dup2);
+#ifdef HAVE_FCNTL64
+       SWRAP_SYMBOL_ENTRY(fcntl64);
+#else
        SWRAP_SYMBOL_ENTRY(fcntl);
+#endif
        SWRAP_SYMBOL_ENTRY(fopen);
 #ifdef HAVE_FOPEN64
        SWRAP_SYMBOL_ENTRY(fopen64);
@@ -978,7 +982,24 @@ static int libc_vfcntl(int fd, int cmd, va_list ap)
 
        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.
+        */
+#ifdef HAVE_FCNTL64
+       rc = swrap.libc.symbols._libc_fcntl64.f(fd, cmd, arg);
+#else
        rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
+#endif
 
        return rc;
 }
@@ -1400,7 +1421,11 @@ static void __swrap_bind_symbol_all_once(void)
        swrap_bind_symbol_libsocket(connect);
        swrap_bind_symbol_libc(dup);
        swrap_bind_symbol_libc(dup2);
+#ifdef HAVE_FCNTL64
+       swrap_bind_symbol_libc(fcntl64);
+#else
        swrap_bind_symbol_libc(fcntl);
+#endif
        swrap_bind_symbol_libc(fopen);
 #ifdef HAVE_FOPEN64
        swrap_bind_symbol_libc(fopen64);