diff options
Diffstat (limited to 'ports/unix/guts/fchmodat.c')
-rw-r--r-- | ports/unix/guts/fchmodat.c | 50 |
1 files changed, 15 insertions, 35 deletions
diff --git a/ports/unix/guts/fchmodat.c b/ports/unix/guts/fchmodat.c index 6ae6d2d..0506794 100644 --- a/ports/unix/guts/fchmodat.c +++ b/ports/unix/guts/fchmodat.c @@ -8,28 +8,17 @@ */ PSEUDO_STATBUF buf; int save_errno = errno; - static int picky_fchmodat = 0; + if (flags & AT_SYMLINK_NOFOLLOW) { + errno = ENOTSUP; + return -1; + } #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS if (dirfd != AT_FDCWD) { errno = ENOSYS; return -1; } - if (flags & AT_SYMLINK_NOFOLLOW) { - /* Linux, as of this writing, will always reject this. - * GNU tar relies on getting the rejection. To cut down - * on traffic, we check for the failure, and if we saw - * a failure previously, we reject it right away and tell - * the caller to retry. - */ - if (picky_fchmodat) { - errno = ENOTSUP; - return -1; - } - rc = base_lstat(path, &buf); - } else { - rc = base_stat(path, &buf); - } + rc = base_stat(path, &buf); #else rc = base_fstatat(dirfd, path, &buf, flags); #endif @@ -47,9 +36,9 @@ pseudo_msg_t *msg; /* purely for debugging purposes: check whether file * is already in database. We don't need the resulting - * information for anything. This is currently ifdefed - * out because it's only useful when trying to track where - * files are coming from. + * information for anything. This is currently ifdefed + * out because it's only useful when trying to track where + * files are coming from. */ msg = pseudo_client_op(OP_STAT, 0, -1, -1, path, &buf); if (!msg || msg->result != RESULT_SUCCEED) { @@ -66,30 +55,21 @@ real_chmod(path, PSEUDO_FS_MODE(mode, S_ISDIR(buf.st_mode))); #else rc = real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, S_ISDIR(buf.st_mode)), flags); - /* AT_SYMLINK_NOFOLLOW isn't supported by fchmodat. GNU tar - * tries to use it anyway, figuring it can just retry if that - * fails. So we want to report that *particular* failure instead - * of doing the fallback. - */ - if (rc == -1 && errno == ENOTSUP && (flags & AT_SYMLINK_NOFOLLOW)) { - picky_fchmodat = 1; - return -1; - } #endif /* we otherwise ignore failures from underlying fchmod, because pseudo * may believe you are permitted to change modes that the filesystem * doesn't. Note that we also don't need to know whether the - * file might be a (pseudo) block device or some such; pseudo - * will only modify permission bits based on an OP_CHMOD, and does - * not care about device/file type mismatches, only directory/file - * or symlink/file. + * file might be a (pseudo) block device or some such; pseudo + * will only modify permission bits based on an OP_CHMOD, and does + * not care about device/file type mismatches, only directory/file + * or symlink/file. */ buf.st_mode = (buf.st_mode & ~07777) | (mode & 07777); pseudo_client_op(OP_CHMOD, 0, -1, dirfd, path, &buf); - /* don't change errno from what it was originally */ - errno = save_errno; - rc = 0; + /* don't change errno from what it was originally */ + errno = save_errno; + rc = 0; /* return rc; * } |