[pacman-dev] [PATCH 1/3] libalpm/util: two stat() related cleanups

Dan McGee dan at archlinux.org
Wed Oct 26 18:44:41 EDT 2011


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 at 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



More information about the pacman-dev mailing list