diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-06-04 22:30:36 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-06-04 22:30:36 +0000 |
commit | c905ff90bdc25ad2ca2be08ce11993dca9cef2ae (patch) | |
tree | d5217918539558115e4e401807c3354b522b6c7a /lib/libarchive/archive_read_extract.c | |
parent | 8abbbb08b15d41b967b0caf34eaefb9c35ebcefa (diff) | |
download | FreeBSD-src-c905ff90bdc25ad2ca2be08ce11993dca9cef2ae.zip FreeBSD-src-c905ff90bdc25ad2ca2be08ce11993dca9cef2ae.tar.gz |
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.
Diffstat (limited to 'lib/libarchive/archive_read_extract.c')
-rw-r--r-- | lib/libarchive/archive_read_extract.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c index 4a8f1d2..eb52e8e 100644 --- a/lib/libarchive/archive_read_extract.c +++ b/lib/libarchive/archive_read_extract.c @@ -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 |