]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
exch: fix compile error if renameat2 is not present
authorThomas Devoogdt <thomas.devoogdt@barco.com>
Thu, 6 Mar 2025 13:18:48 +0000 (14:18 +0100)
committerThomas Devoogdt <thomas.devoogdt@barco.com>
Fri, 7 Mar 2025 14:03:28 +0000 (15:03 +0100)
https://www.man7.org/linux/man-pages/man2/rename.2.html
Available since Linux 3.15 or glibc 2.28,
add a fallback for older systems.

My initial implementation did the exchange using a swap
file if both HAVE_RENAMEAT2 and SYS_renameat2 were absent.
But that is not really what is desired since exch is supposed
to be atomic. So simply return -1 renameat2 is available.

Signed-off-by: Thomas Devoogdt <thomas.devoogdt@barco.com>
misc-utils/exch.c

index 93a9f770313883b0fee6858e69ec064245489ccb..1789fa6559474fcab88d66fc0ee7574398f94f5c 100644 (file)
 # define RENAME_EXCHANGE (1 << 1)
 #endif
 
-#if !defined(HAVE_RENAMEAT2) && defined(SYS_renameat2)
-static inline int renameat2(int olddirfd, const char *oldpath,
-                           int newdirfd, const char *newpath, unsigned int flags)
-{
-       return syscall (SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
-}
+static inline int rename_exchange(int dirfd,
+                                 const char *oldpath, const char *newpath) {
+       int rc;
+
+#if defined(HAVE_RENAMEAT2)
+       rc = renameat2(dirfd, oldpath, dirfd, newpath, RENAME_EXCHANGE);
+#elif defined(SYS_renameat2)
+       rc = syscall(SYS_renameat2,
+                    dirfd, oldpath, dirfd, newpath, RENAME_EXCHANGE);
+#else
+       rc = -1;
+       errno = ENOSYS;
 #endif
 
+       return rc;
+}
+
 static void __attribute__((__noreturn__)) usage(void)
 {
        FILE *out = stdout;
@@ -85,8 +94,7 @@ int main(int argc, char **argv)
                errtryhelp(EXIT_FAILURE);
        }
 
-       rc = renameat2(AT_FDCWD, argv[optind],
-                      AT_FDCWD, argv[optind + 1], RENAME_EXCHANGE);
+       rc = rename_exchange(AT_FDCWD, argv[optind], argv[optind + 1]);
        if (rc)
                warn(_("failed to exchange \"%s\" and \"%s\""),
                     argv[optind], argv[optind + 1]);