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;