---
ls.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/ls.c b/ls.c
index b716aba..c01a277 100644
--- a/ls.c
+++ b/ls.c
_AT_@ -10,6 +10,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <errno.h>
#include "utf.h"
#include "util.h"
_AT_@ -58,15 +59,29 @@ static int showdirs;
static void ls(const char *, const struct entry *, int);
static void
-mkent(struct entry *ent, char *path, int dostat, int follow)
+mkent(struct entry *ent, char *prefix, char *name, int dostat, int follow,
+ int fatal)
{
struct stat st;
+ char path[PATH_MAX];
- ent->name = path;
+ ent->name = name;
if (!dostat)
return;
- if ((follow ? stat : lstat)(path, &st) < 0)
- eprintf("%s %s:", follow ? "stat" : "lstat", path);
+
+ if (prefix != NULL)
+ snprintf(path, PATH_MAX, "%s/%s", prefix, name);
+ else
+ strncpy(path, name, PATH_MAX);
+
+ if ((follow ? stat : lstat)(path, &st) < 0) {
+ if (errno == EACCES && !fatal) {
+ weprintf("%s %s:", follow ? "stat" : "lstat", path);
+ return;
+ } else {
+ eprintf("%s %s:", follow ? "stat" : "lstat", path);
+ }
+ }
ent->mode = st.st_mode;
ent->nlink = st.st_nlink;
ent->uid = st.st_uid;
_AT_@ -252,8 +267,6 @@ lsdir(const char *path, const struct entry *dir)
weprintf("opendir %s%s:", path, dir->name);
return;
}
- if (chdir(dir->name) < 0)
- eprintf("chdir %s:", dir->name);
while ((d = readdir(dp))) {
if (d->d_name[0] == '.' && !aflag && !Aflag)
_AT_@ -264,8 +277,8 @@ lsdir(const char *path, const struct entry *dir)
continue;
ents = ereallocarray(ents, ++n, sizeof(*ents));
- mkent(&ents[n - 1], estrdup(d->d_name), Fflag || iflag ||
- lflag || pflag || Rflag || sort, Lflag);
+ mkent(&ents[n - 1], dir->name, estrdup(d->d_name), Fflag || iflag ||
+ lflag || pflag || Rflag || sort, Lflag, 0);
}
closedir(dp);
_AT_@ -446,7 +459,7 @@ main(int argc, char *argv[])
case 0: /* fallthrough */
*--argv = ".", ++argc;
case 1:
- mkent(&ent, argv[0], 1, Hflag || Lflag);
+ mkent(&ent, NULL, argv[0], 1, Hflag || Lflag, 1);
ls("", &ent, (!dflag && S_ISDIR(ent.mode)) ||
(S_ISLNK(ent.mode) && S_ISDIR(ent.tmode) &&
!(dflag || Fflag || lflag)));
_AT_@ -454,7 +467,7 @@ main(int argc, char *argv[])
break;
default:
for (i = ds = fs = 0, fents = dents = NULL; i < argc; ++i) {
- mkent(&ent, argv[i], 1, Hflag || Lflag);
+ mkent(&ent, NULL, argv[i], 1, Hflag || Lflag, 1);
if ((!dflag && S_ISDIR(ent.mode)) ||
(S_ISLNK(ent.mode) && S_ISDIR(ent.tmode) &&
--
2.14.2
This archive was generated by hypermail 2.3.0 : Tue Oct 17 2017 - 11:36:29 CEST