From: Thomas Devoogdt Date: Thu, 6 Mar 2025 13:18:48 +0000 (+0100) Subject: exch: fix compile error if renameat2 is not present X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=72a99516f7bdf72411501d0a04cc8f8a7e562d10;p=thirdparty%2Futil-linux.git exch: fix compile error if renameat2 is not present 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 --- diff --git a/misc-utils/exch.c b/misc-utils/exch.c index 93a9f7703..1789fa655 100644 --- a/misc-utils/exch.c +++ b/misc-utils/exch.c @@ -26,14 +26,23 @@ # 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]);