diff options
| -rw-r--r-- | cftw.c | 36 |
1 files changed, 24 insertions, 12 deletions
@@ -101,11 +101,14 @@ failure: return NULL; } -static enum cftw_state run(struct cftw *const c, struct cftw_entry *const e) +static enum cftw_state run(struct cftw *const c, struct cftw_entry *const e, + struct cftw_entry *const root) { - int error; + int error = 0; struct dirent *de; struct dynstr d; + const char *const dirpath = e->dirpath; + struct stat sb; dynstr_init(&d); errno = 0; @@ -117,15 +120,25 @@ static enum cftw_state run(struct cftw *const c, struct cftw_entry *const e) goto failure; } else if (!de) - return CFTW_OK; + { + if (e == root) + return CFTW_OK; + else if (stat(dirpath, &sb)) + { + fprintf(stderr, "%s: stat(2) %s: %s\n", __func__, dirpath, + strerror(errno)); + goto failure; + } - const char *const path = de->d_name, *const dirpath = e->dirpath; + return c->fn(dirpath, &sb, &c->done, c->user) ? CFTW_FATAL : CFTW_OK; + } + + const char *const path = de->d_name; if (!strcmp(path, ".") || !strcmp(path, "..")) return CFTW_AGAIN; const char *const sep = dirpath[strlen(dirpath) - 1] == '/' ? "" : "/"; - struct stat sb; if (dynstr_append(&d, "%s%s%s", dirpath, sep, path)) { @@ -145,8 +158,6 @@ static enum cftw_state run(struct cftw *const c, struct cftw_entry *const e) { if (!(e->child = entry(d.str))) goto failure; - - error = c->fn(d.str, &sb, &c->done, c->user); } else if (S_ISREG(sb.st_mode)) error = c->fn(d.str, &sb, &c->done, c->user); @@ -171,11 +182,12 @@ failure: return CFTW_FATAL; } -static enum cftw_state step(struct cftw *const c, struct cftw_entry *const e) +static enum cftw_state step(struct cftw *const c, struct cftw_entry *const e, + struct cftw_entry *const root) { if (e->child) { - switch (step(c, e->child)) + switch (step(c, e->child, root)) { case CFTW_AGAIN: return CFTW_AGAIN; @@ -195,12 +207,12 @@ static enum cftw_state step(struct cftw *const c, struct cftw_entry *const e) return CFTW_AGAIN; } - return run(c, e); + return run(c, e, root); } -enum cftw_state cftw_step(struct cftw *c) +enum cftw_state cftw_step(struct cftw *const c) { - return step(c, c->root); + return step(c, c->root, c->root); } struct cftw *cftw(const char *const dirpath, int (*const fn)(const char *, |
