From: Wayne Davison Date: Sun, 29 Nov 2020 17:33:54 +0000 (-0800) Subject: Work around glibc's lchmod() issue a better way. X-Git-Tag: v3.2.4pre1~106 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9dd62525f3b98d692e031f22c02be8f775966503;p=thirdparty%2Frsync.git Work around glibc's lchmod() issue a better way. --- diff --git a/configure.ac b/configure.ac index 19d6ae52..0f8e38f3 100644 --- a/configure.ac +++ b/configure.ac @@ -901,14 +901,6 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd chown chmod lchmod mknod mkfifo \ extattr_get_link sigaction sigprocmask setattrlist getgrouplist \ initgroups utimensat posix_fallocate attropen setvbuf nanosleep usleep) -case "$host_os" in -*linux*) # Work around a glibc bug. TODO eventually remove this? - ac_cv_func_lchmod=no - grep -v HAVE_LCHMOD confdefs.h >confdefs.h.new - mv confdefs.h.new confdefs.h - ;; -esac - dnl cygwin iconv.h defines iconv_open as libiconv_open if test x"$ac_cv_func_iconv_open" != x"yes"; then AC_CHECK_FUNC(libiconv_open, [ac_cv_func_iconv_open=yes; AC_DEFINE(HAVE_ICONV_OPEN, 1)]) diff --git a/syscall.c b/syscall.c index b9c3b4ef..11d10e4a 100644 --- a/syscall.c +++ b/syscall.c @@ -227,27 +227,35 @@ int do_open(const char *pathname, int flags, mode_t mode) #ifdef HAVE_CHMOD int do_chmod(const char *path, mode_t mode) { + static int switch_step = 0; int code; if (dry_run) return 0; RETURN_ERROR_IF_RO_OR_LO; + switch (switch_step) { #ifdef HAVE_LCHMOD - code = lchmod(path, mode & CHMOD_BITS); -#else - if (S_ISLNK(mode)) { +#include "case_N.h" + if ((code = lchmod(path, mode & CHMOD_BITS)) == 0 || errno != ENOTSUP) + break; + switch_step++; +#endif + +#include "case_N.h" + if (S_ISLNK(mode)) { # if defined HAVE_SETATTRLIST - struct attrlist attrList; - uint32_t m = mode & CHMOD_BITS; /* manpage is wrong: not mode_t! */ + struct attrlist attrList; + uint32_t m = mode & CHMOD_BITS; /* manpage is wrong: not mode_t! */ - memset(&attrList, 0, sizeof attrList); - attrList.bitmapcount = ATTR_BIT_MAP_COUNT; - attrList.commonattr = ATTR_CMN_ACCESSMASK; - code = setattrlist(path, &attrList, &m, sizeof m, FSOPT_NOFOLLOW); + memset(&attrList, 0, sizeof attrList); + attrList.bitmapcount = ATTR_BIT_MAP_COUNT; + attrList.commonattr = ATTR_CMN_ACCESSMASK; + code = setattrlist(path, &attrList, &m, sizeof m, FSOPT_NOFOLLOW); # else - code = 1; + code = 1; # endif - } else - code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */ -#endif /* !HAVE_LCHMOD */ + } else + code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */ + break; + } if (code != 0 && (preserve_perms || preserve_executability)) return code; return 0;