First, use fstat() in preference to stat() since we already have an open file handle. This also removes the need to check for a symlink as that is not possible when a file is opened. Next, use archive_entry_mode() rather than archive_entry_stat() as we only use the mode portion of the stat struct and the call is much cheaper. Also delay it until it is necessary. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/util.c | 27 +++++++++++++-------------- 1 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 0d499ad..af9cf42 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -160,12 +160,10 @@ int _alpm_copyfile(const char *src, const char *dest) } } - /* chmod dest to permissions of src, as long as it is not a symlink */ + /* chmod dest to permissions of src */ struct stat statbuf; - if(!stat(src, &statbuf)) { - if(! S_ISLNK(statbuf.st_mode)) { - fchmod(fileno(out), statbuf.st_mode); - } + if(!fstat(fileno(in), &statbuf)) { + fchmod(fileno(out), statbuf.st_mode); } else { /* stat was unsuccessful */ ret = 1; @@ -313,18 +311,11 @@ int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix, } while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) { - const struct stat *st; - const char *entryname; /* the name of the file in the archive */ + const char *entryname; + mode_t mode; - st = archive_entry_stat(entry); entryname = archive_entry_pathname(entry); - if(S_ISREG(st->st_mode)) { - archive_entry_set_perm(entry, 0644); - } else if(S_ISDIR(st->st_mode)) { - archive_entry_set_perm(entry, 0755); - } - /* If specific files were requested, skip entries that don't match. */ if(list) { char *entry_prefix = strdup(entryname); @@ -345,6 +336,13 @@ int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix, } } + mode = archive_entry_mode(entry); + if(S_ISREG(mode)) { + archive_entry_set_perm(entry, 0644); + } else if(S_ISDIR(mode)) { + archive_entry_set_perm(entry, 0755); + } + /* Extract the archive entry. */ int readret = archive_read_extract(_archive, entry, 0); if(readret == ARCHIVE_WARN) { @@ -555,6 +553,7 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *path, char *const argv[] } umask(0022); execv(path, argv); + /* execv only returns if there was an error */ fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno)); exit(1); } else { -- 1.7.7