libutil/recurse: only opendir if recursing

Previous behaviour was to call opendir regardless of if we are actually going
to be recursing into the directory. Additionally, some utilities that use
DIRFIRST benefit from running the function pointed to by fn before the call
to opendir. One such example is `chmod [-R] 777 dir` on a directory with mode
000, where it will be expected for chmod to first give itself rwx before
optionally listing the directory to traverse it.
This commit is contained in:
David Phillips 2017-10-01 21:39:27 +13:00 committed by Michael Forney
parent e6d3032131
commit 69b9c2444b
1 changed files with 8 additions and 10 deletions

View File

@ -54,18 +54,17 @@ recurse(const char *path, void *data, struct recursor *r)
if (h->ino == st.st_ino && h->dev == st.st_dev) if (h->ino == st.st_ino && h->dev == st.st_dev)
return; return;
if (!(dp = opendir(path))) {
if (!(r->flags & SILENT)) {
weprintf("opendir %s:", path);
recurse_status = 1;
}
return;
}
if (!r->depth && (r->flags & DIRFIRST)) if (!r->depth && (r->flags & DIRFIRST))
(r->fn)(path, &st, data, r); (r->fn)(path, &st, data, r);
if (!r->maxdepth || r->depth + 1 < r->maxdepth) { if (!r->maxdepth || r->depth + 1 < r->maxdepth) {
if (!(dp = opendir(path))) {
if (!(r->flags & SILENT)) {
weprintf("opendir %s:", path);
recurse_status = 1;
}
return;
}
while ((d = readdir(dp))) { while ((d = readdir(dp))) {
if (r->follow == 'H') { if (r->follow == 'H') {
statf_name = "lstat"; statf_name = "lstat";
@ -90,6 +89,7 @@ recurse(const char *path, void *data, struct recursor *r)
r->depth--; r->depth--;
} }
} }
closedir(dp);
} }
if (!r->depth) { if (!r->depth) {
@ -102,6 +102,4 @@ recurse(const char *path, void *data, struct recursor *r)
free(h); free(h);
} }
} }
closedir(dp);
} }