Index: scanelf.c =================================================================== RCS file: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v retrieving revision 1.159 diff -u -p -r1.159 scanelf.c --- scanelf.c 29 Oct 2006 16:20:54 -0000 1.159 +++ scanelf.c 28 Nov 2006 01:03:30 -0000 @@ -29,7 +29,7 @@ static int file_matches_list(const char static int scanelf_elfobj(elfobj *elf); static int scanelf_elf(const char *filename, int fd, size_t len); static int scanelf_archive(const char *filename, int fd, size_t len); -static void scanelf_file(const char *filename); +static void scanelf_file(const char *filename, const struct stat *st_cache); static void scanelf_dir(const char *path); static void scanelf_ldpath(void); static void scanelf_envpath(void); @@ -1231,23 +1231,30 @@ static int scanelf_archive(const char *f return 0; } /* scan a file which may be an elf or an archive or some other magical beast */ -static void scanelf_file(const char *filename) +static void scanelf_file(const char *filename, const struct stat *st_cache) { - struct stat st; + const struct stat *st; + struct stat my_st; int fd; - /* make sure 'filename' exists */ - if (lstat(filename, &st) == -1) { - if (be_verbose > 2) printf("%s: does not exist\n", filename); - return; - } + /* use stat cache if we have one */ + if (!st_cache) { + /* make sure 'filename' exists */ + if (lstat(filename, &my_st) == -1) { + if (be_verbose > 2) printf("%s: does not exist\n", filename); + return; + } + st = &my_st; + } else + st = st_cache; /* always handle regular files and handle symlinked files if no -y */ - if (S_ISLNK(st.st_mode)) { + if (S_ISLNK(st->st_mode)) { if (!scan_symlink) return; - stat(filename, &st); + stat(filename, &my_st); + st = &my_st; } - if (!S_ISREG(st.st_mode)) { + if (!S_ISREG(st->st_mode)) { if (be_verbose > 2) printf("%s: skipping non-file\n", filename); return; } @@ -1255,9 +1262,9 @@ static void scanelf_file(const char *fil if ((fd=open(filename, (fix_elf ? O_RDWR : O_RDONLY))) == -1) return; - if (scanelf_elf(filename, fd, st.st_size) == 1 && scan_archives) + if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives) /* if it isn't an ELF, maybe it's an .a archive */ - scanelf_archive(filename, fd, st.st_size); + scanelf_archive(filename, fd, st->st_size); close(fd); } @@ -1279,7 +1286,7 @@ static void scanelf_dir(const char *path /* ok, if it isn't a directory, assume we can open it */ if (!S_ISDIR(st_top.st_mode)) { - scanelf_file(path); + scanelf_file(path, &st_top); return; } @@ -1303,7 +1310,7 @@ static void scanelf_dir(const char *path snprintf(buf, sizeof(buf), "%s%s%s", path, (path[pathlen-1] == '/') ? "" : "/", dentry->d_name); if (lstat(buf, &st) != -1) { if (S_ISREG(st.st_mode)) - scanelf_file(buf); + scanelf_file(buf, &st); else if (dir_recurse && S_ISDIR(st.st_mode)) { if (dir_crossmount || (st_top.st_dev == st.st_dev)) scanelf_dir(buf);