changeset 735:3aaba60133c8

Have dirtree_add_node() set parent so error message can provide full path.
author Rob Landley <rob@landley.net>
date Thu, 06 Dec 2012 15:13:30 -0600
parents 7e0cea8fbc3e
children e7694c640f36
files lib/dirtree.c lib/lib.h toys/posix/chgrp.c toys/posix/du.c toys/posix/ls.c
diffstat 5 files changed, 34 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/lib/dirtree.c	Mon Dec 03 16:16:06 2012 -0600
+++ b/lib/dirtree.c	Thu Dec 06 15:13:30 2012 -0600
@@ -5,11 +5,27 @@
 
 #include "toys.h"
 
+static int notdotdot(char *name)
+{
+  if (name[0]=='.' && (!name[1] || (name[1]=='.' && !name[2]))) return 0;
+
+  return 1;
+}
+
+// Default callback, filters out "." and "..".
+
+int dirtree_notdotdot(struct dirtree *catch)
+{
+  // Should we skip "." and ".."?
+  return notdotdot(catch->name) ? DIRTREE_SAVE|DIRTREE_RECURSE : 0;
+}
+
 // Create a dirtree node from a path, with stat and symlink info.
 // (This doesn't open directory filehandles yet so as not to exhaust the
 // filehandle space on large trees. handle_callback() does that instead.)
 
-struct dirtree *dirtree_add_node(int dirfd, char *name, int symfollow)
+struct dirtree *dirtree_add_node(struct dirtree *parent, char *name,
+  int symfollow)
 {
   struct dirtree *dt = NULL;
   struct stat st;
@@ -17,15 +33,18 @@
   int len = 0, linklen = 0;
 
   if (name) {
-    if (fstatat(dirfd, name, &st, symfollow ? 0 : AT_SYMLINK_NOFOLLOW))
-      goto error;
+    // open code this because haven't got node to call dirtree_parentfd() on yet
+    int fd = parent ? parent->data : AT_FDCWD;
+
+    if (fstatat(fd, name, &st, symfollow ? 0 : AT_SYMLINK_NOFOLLOW)) goto error;
     if (S_ISLNK(st.st_mode)) {
-      if (0>(linklen = readlinkat(dirfd, name, buf, 4095))) goto error;
+      if (0>(linklen = readlinkat(fd, name, buf, 4095))) goto error;
       buf[linklen++]=0;
     }
     len = strlen(name);
   }
   dt = xzalloc((len = sizeof(struct dirtree)+len+1)+linklen);
+  dt->parent = parent;
   if (name) {
     memcpy(&(dt->st), &st, sizeof(struct stat));
     strcpy(dt->name, name);
@@ -39,7 +58,10 @@
   return dt;
 
 error:
-  perror_msg("%s",name);
+  if (notdotdot(name)) {
+    char *path = parent ? dirtree_path(parent, 0) : "";
+    perror_msg("%s%s%s",path, parent ? "/" : "", name);
+  }
   free(dt);
   return 0;
 }
@@ -66,17 +88,6 @@
   return path;
 }
 
-// Default callback, filters out "." and "..".
-
-int dirtree_notdotdot(struct dirtree *catch)
-{
-  // Should we skip "." and ".."?
-  if (catch->name[0]=='.' && (!catch->name[1] ||
-      (catch->name[1]=='.' && !catch->name[2]))) return 0;
-
-  return DIRTREE_SAVE|DIRTREE_RECURSE;
-}
-
 int dirtree_parentfd(struct dirtree *node)
 {
   return node->parent ? node->parent->data : AT_FDCWD;
@@ -140,9 +151,8 @@
 
   // The extra parentheses are to shut the stupid compiler up.
   while ((entry = readdir(dir))) {
-    if (!(new = dirtree_add_node(node->data, entry->d_name, symfollow)))
+    if (!(new = dirtree_add_node(node, entry->d_name, symfollow)))
       continue;
-    new->parent = node;
     new = handle_callback(new, callback);
     if (new == DIRTREE_ABORTVAL) break;
     if (new) {
@@ -163,7 +173,7 @@
 
 struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node))
 {
-  struct dirtree *root = dirtree_add_node(AT_FDCWD, path, 0);
+  struct dirtree *root = dirtree_add_node(0, path, 0);
 
   return root ? handle_callback(root, callback) : DIRTREE_ABORTVAL;
 }
--- a/lib/lib.h	Mon Dec 03 16:16:06 2012 -0600
+++ b/lib/lib.h	Thu Dec 06 15:13:30 2012 -0600
@@ -70,7 +70,7 @@
   char name[];
 };
 
-struct dirtree *dirtree_add_node(int dirfd, char *name, int symfollow);
+struct dirtree *dirtree_add_node(struct dirtree *p, char *name, int symfollow);
 char *dirtree_path(struct dirtree *node, int *plen);
 int dirtree_notdotdot(struct dirtree *catch);
 int dirtree_parentfd(struct dirtree *node);
--- a/toys/posix/chgrp.c	Mon Dec 03 16:16:06 2012 -0600
+++ b/toys/posix/chgrp.c	Thu Dec 06 15:13:30 2012 -0600
@@ -71,7 +71,7 @@
 
 void chgrp_main(void)
 {
-  int ischown = toys.which->name[2] == 'o';
+  int ischown = toys.which->name[2] == 'o', hl = toys.optflags&(FLAG_H|FLAG_L);
   char **s, *own;
 
   // Distinguish chown from chgrp
@@ -103,8 +103,7 @@
   }
 
   for (s=toys.optargs+1; *s; s++) {
-    struct dirtree *new = dirtree_add_node(AT_FDCWD, *s,
-      toys.optflags&(FLAG_H|FLAG_L));
+    struct dirtree *new = dirtree_add_node(0, *s, hl);
     if (new) handle_callback(new, do_chgrp);
     else toys.exitval = 1;
   }
--- a/toys/posix/du.c	Mon Dec 03 16:16:06 2012 -0600
+++ b/toys/posix/du.c	Thu Dec 06 15:13:30 2012 -0600
@@ -203,7 +203,7 @@
   while(*toys.optargs) {
     TT.depth = 0;
     char *path = make_pathproper(*toys.optargs);
-    struct dirtree *root = dirtree_add_node(AT_FDCWD, path, symfollow); //create a node
+    struct dirtree *root = dirtree_add_node(0, path, symfollow);
     if(root) {
       TT.st_dev = root->st.st_dev;
       handle_callback(root, do_du); //this will recurse thru the DIR children.
--- a/toys/posix/ls.c	Mon Dec 03 16:16:06 2012 -0600
+++ b/toys/posix/ls.c	Thu Dec 06 15:13:30 2012 -0600
@@ -436,7 +436,7 @@
   // Non-absolute paths are relative to current directory.
   TT.files = dirtree_add_node(0, 0, 0);
   for (s = *toys.optargs ? toys.optargs : noargs; *s; s++) {
-    dt = dirtree_add_node(AT_FDCWD, *s,
+    dt = dirtree_add_node(0, *s,
       (toys.optflags & (FLAG_L|FLAG_H|FLAG_l))^FLAG_l);
 
     if (!dt) {