| diff --git a/syscall.c b/syscall.c |
| index b9c3b4ef..11d10e4a 100644 |
| |
| |
| @@ -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; |