Minor clean up for flags restoration: Use fchflags/lchflags when

available, stub out flags restore on platforms that don't support it,
update autoconf to probe for fchflags and lchflags support.
This commit is contained in:
Tim Kientzle 2005-06-04 22:30:36 +00:00
parent 48864d8c25
commit 495b0c0d52
4 changed files with 52 additions and 13 deletions

View File

@ -7,7 +7,7 @@
LIB= archive
VERSION= 1.02.023
VERSION= 1.02.026
ARCHIVE_API_FEATURE= 2
ARCHIVE_API_VERSION= 1
SHLIB_MAJOR= ${ARCHIVE_API_VERSION}

View File

@ -57,11 +57,13 @@
#define HAVE_EILSEQ 1
#define HAVE_ERRNO_H 1
#define HAVE_FCHDIR 1
#define HAVE_FCHFLAGS 1
#define HAVE_FCHMOD 1
#define HAVE_FCHOWN 1
#define HAVE_FCNTL_H 1
#define HAVE_FUTIMES 1
#define HAVE_INTTYPES_H 1
#define HAVE_LCHFLAGS 1
#define HAVE_LCHMOD 1
#define HAVE_LCHOWN 1
#define HAVE_LIMITS_H 1
@ -133,7 +135,7 @@
* for compatibility's sake, close files before trying to restore metadata.
*/
#if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN)
#define CAN_RESTORE_METADATA_FD
#define CAN_RESTORE_METADATA_FD
#endif
/* Set up defaults for internal error codes. */

View File

@ -1142,7 +1142,7 @@ set_perm(struct archive *a, int fd, struct archive_entry *entry,
}
#if defined(HAVE_CHFLAGS) && !defined(__linux)
#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && !defined(__linux)
static int
set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
unsigned long set, unsigned long clear)
@ -1174,17 +1174,34 @@ set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
extract->st.st_flags &= ~clear;
extract->st.st_flags |= set;
#ifdef HAVE_FCHFLAGS
/* If platform has fchflags() and we were given an fd, use it. */
if (fd >= 0 && fchflags(fd, extract->st.st_flags) == 0)
return (ARCHIVE_OK);
#endif
/*
* If we can't use the fd to set the flags, we'll use the
* pathname to set flags. We prefer lchflags() but will use
* chflags() if we must.
*/
#ifdef HAVE_LCHFLAGS
if (lchflags(name, extract->st.st_flags) == 0)
return (ARCHIVE_OK);
#elif defined(HAVE_CHFLAGS)
if (chflags(name, extract->st.st_flags) == 0)
return (ARCHIVE_OK);
#endif
archive_set_error(a, errno,
"Failed to set file flags");
return (ARCHIVE_WARN);
}
#endif /* HAVE_CHFLAGS */
#ifdef __linux
/* Linux has flags too, but uses ioctl() instead of chflags(). */
#elif defined(__linux)
/*
* Linux has flags too, but uses ioctl() to access them instead of
* having a separate chflags() system call.
*/
static int
set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
unsigned long set, unsigned long clear)
@ -1196,18 +1213,17 @@ set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
unsigned long newflags, oldflags;
extract = a->extract;
ret = ARCHIVE_OK;
if (set == 0 && clear == 0)
return (ret);
return (ARCHIVE_OK);
/* Only regular files and dirs can have flags. */
if (!S_ISREG(mode) && !S_ISDIR(mode))
return (ret);
return (ARCHIVE_OK);
/* If we weren't given an fd, open it ourselves. */
if (myfd < 0)
myfd = open(name, O_RDONLY|O_NONBLOCK);
if (myfd < 0)
return (ret);
return (ARCHIVE_OK);
/*
* Linux has no define for the flags that are only settable
@ -1218,6 +1234,7 @@ set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
* XXX As above, this would be way simpler if we didn't have
* to read the current flags from disk. XXX
*/
ret = ARCHIVE_OK;
/* Try setting the flags as given. */
if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
newflags = (oldflags & ~clear) | set;
@ -1244,6 +1261,26 @@ cleanup:
close(myfd);
return (ret);
}
#else /* Not HAVE_CHFLAGS && Not __linux */
/*
* Of course, some systems have neither BSD chflags() nor Linux' flags
* support through ioctl().
*/
static int
set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
unsigned long set, unsigned long clear)
{
(void)a;
(void)fd;
(void)name;
(void)mode;
(void)set;
(void)clear;
return (ARCHIVE_OK);
}
#endif /* __linux */
#ifndef HAVE_POSIX_ACL

View File

@ -73,8 +73,8 @@ AC_FUNC_MEMCMP
AC_FUNC_STAT
AC_FUNC_STRERROR_R
AC_CHECK_FUNCS([acl_create_entry acl_init acl_set_fd acl_set_fd_np acl_set_file])
AC_CHECK_FUNCS([chflags fchdir fchmod fchown futimes])
AC_CHECK_FUNCS([lchmod lchown lutimes memmove])
AC_CHECK_FUNCS([chflags fchdir fchflags fchmod fchown futimes])
AC_CHECK_FUNCS([lchflags lchmod lchown lutimes memmove])
AC_CHECK_FUNCS([memset mkdir mkfifo strchr strdup strerror strrchr])
# Additional requirements