]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
build: fall back to do_mknod() when mknodat() is unavailable (#896)
authorAndrew Tridgell <andrew@tridgell.net>
Thu, 4 Jun 2026 04:46:38 +0000 (14:46 +1000)
committerAndrew Tridgell <andrew@tridgell.net>
Thu, 4 Jun 2026 20:35:12 +0000 (06:35 +1000)
do_mknod_at() (the symlink-race-safe variant used by a non-chrooted
daemon receiver) calls mknodat()/mkfifoat(), but the at-variant was
gated only on AT_FDCWD.  Older Darwin declares AT_FDCWD without
mknodat(), so the build failed with "mknodat undeclared".

Probe mknodat()/mkfifoat() in configure and require HAVE_MKNODAT for the
at-variant; without it do_mknod_at() falls back to do_mknod(), exactly
as it already does where AT_FDCWD is missing.  Linux keeps the mknodat
path since HAVE_MKNODAT is defined there.

Fixes: #896
configure.ac
syscall.c

index c4166c3c7e1b7f0c33be6fa48b8c9afce6e967aa..cfccb37cba499cfeb8764766d7d60033e99871f3 100644 (file)
@@ -932,7 +932,7 @@ AC_FUNC_UTIME_NULL
 AC_FUNC_ALLOCA
 AC_CHECK_FUNCS(waitpid wait4 getcwd chown chmod lchmod mknod mkfifo \
     fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
-    chflags getattrlist mktime innetgr linkat \
+    chflags getattrlist mktime innetgr linkat mknodat mkfifoat \
     memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
     strlcat strlcpy stpcpy strtol mallinfo mallinfo2 getgroups setgroups geteuid getegid \
     setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
index 3f023462b93cd2ad56635a6a8ae70291d90d7542..243f7f243f3dc73f6e1ab4b1ddd4da503292443c 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -536,7 +536,9 @@ int do_mknod(const char *pathname, mode_t mode, dev_t dev)
 */
 int do_mknod_at(const char *pathname, mode_t mode, dev_t dev)
 {
-#ifdef AT_FDCWD
+       /* HAVE_MKNODAT: older Darwin declares AT_FDCWD but not mknodat(), so
+        * the at-variant won't build there; fall back to do_mknod() (#896). */
+#if defined(AT_FDCWD) && defined(HAVE_MKNODAT)
        extern int am_daemon, am_chrooted;
        char dirpath[MAXPATHLEN];
        const char *bname;
@@ -598,7 +600,7 @@ int do_mknod_at(const char *pathname, mode_t mode, dev_t dev)
                return ret;
        }
 
-#if !defined MKNOD_CREATES_FIFOS && defined HAVE_MKFIFO
+#if !defined MKNOD_CREATES_FIFOS && defined HAVE_MKFIFO && defined HAVE_MKFIFOAT
        if (S_ISFIFO(mode))
                ret = mkfifoat(dfd, bname, mode);
        else