fts_read: Handle error from a NULL return better.
This is addressing cases such as fts_read(3) encountering an [EIO] from fchdir(2) when FTS_NOCHDIR is not set. That would otherwise be seen as a successful traversal in some of these cases while silently discarding expected work. As noted in r264201, fts_read() does not set errno to 0 on a successful EOF so it needs to be set before calling it. Otherwise we might see a random error from one of the iterations. gzip is ignoring most errors and could be improved separately. Reviewed by: vangyzen Sponsored by: Dell EMC Differential Revision: https://reviews.freebsd.org/D27184
This commit is contained in:
parent
f1b18a668d
commit
2dfa4b66b3
@ -163,7 +163,7 @@ main(int argc, char *argv[])
|
|||||||
if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL)
|
if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL)
|
||||||
err(1, NULL);
|
err(1, NULL);
|
||||||
|
|
||||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
for (rval = 0; errno = 0, (p = fts_read(ftsp)) != NULL;) {
|
||||||
int atflag;
|
int atflag;
|
||||||
|
|
||||||
if ((fts_options & FTS_LOGICAL) ||
|
if ((fts_options & FTS_LOGICAL) ||
|
||||||
|
@ -164,7 +164,7 @@ done: argv += optind;
|
|||||||
|
|
||||||
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
|
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
|
||||||
err(1, "fts_open");
|
err(1, "fts_open");
|
||||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
for (rval = 0; errno = 0, (p = fts_read(ftsp)) != NULL;) {
|
||||||
int atflag;
|
int atflag;
|
||||||
|
|
||||||
if ((fts_options & FTS_LOGICAL) ||
|
if ((fts_options & FTS_LOGICAL) ||
|
||||||
|
@ -282,7 +282,8 @@ copy(char *argv[], enum op type, int fts_options)
|
|||||||
|
|
||||||
if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
|
if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
|
||||||
err(1, "fts_open");
|
err(1, "fts_open");
|
||||||
for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp = 0) {
|
for (badcp = rval = 0; errno = 0, (curr = fts_read(ftsp)) != NULL;
|
||||||
|
badcp = 0) {
|
||||||
switch (curr->fts_info) {
|
switch (curr->fts_info) {
|
||||||
case FTS_NS:
|
case FTS_NS:
|
||||||
case FTS_DNR:
|
case FTS_DNR:
|
||||||
|
@ -645,7 +645,7 @@ traverse(int argc, char *argv[], int options)
|
|||||||
ch_options = !f_recursive && !f_label &&
|
ch_options = !f_recursive && !f_label &&
|
||||||
options & FTS_NOSTAT ? FTS_NAMEONLY : 0;
|
options & FTS_NOSTAT ? FTS_NAMEONLY : 0;
|
||||||
|
|
||||||
while ((p = fts_read(ftsp)) != NULL)
|
while (errno = 0, (p = fts_read(ftsp)) != NULL)
|
||||||
switch (p->fts_info) {
|
switch (p->fts_info) {
|
||||||
case FTS_DC:
|
case FTS_DC:
|
||||||
warnx("%s: directory causes a cycle", p->fts_name);
|
warnx("%s: directory causes a cycle", p->fts_name);
|
||||||
|
@ -207,7 +207,7 @@ rm_tree(char **argv)
|
|||||||
return;
|
return;
|
||||||
err(1, "fts_open");
|
err(1, "fts_open");
|
||||||
}
|
}
|
||||||
while ((p = fts_read(fts)) != NULL) {
|
while (errno = 0, (p = fts_read(fts)) != NULL) {
|
||||||
switch (p->fts_info) {
|
switch (p->fts_info) {
|
||||||
case FTS_DNR:
|
case FTS_DNR:
|
||||||
if (!fflag || p->fts_errno != ENOENT) {
|
if (!fflag || p->fts_errno != ENOENT) {
|
||||||
|
@ -498,8 +498,10 @@ main(int argc, char *argv[])
|
|||||||
/* Open all files. */
|
/* Open all files. */
|
||||||
if ((ftsp = fts_open(files_list, fts_options | FTS_NOSTAT, 0)) == NULL)
|
if ((ftsp = fts_open(files_list, fts_options | FTS_NOSTAT, 0)) == NULL)
|
||||||
err(1, "fts_open");
|
err(1, "fts_open");
|
||||||
while ((file = fts_read(ftsp)) != NULL)
|
while (errno = 0, (file = fts_read(ftsp)) != NULL)
|
||||||
carried_error += handle_file(ftsp, file);
|
carried_error += handle_file(ftsp, file);
|
||||||
|
if (errno != 0)
|
||||||
|
err(1, "fts_read");
|
||||||
|
|
||||||
return (carried_error);
|
return (carried_error);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ cwalk(FILE *fp)
|
|||||||
|
|
||||||
if ((t = fts_open(argv, ftsoptions, dcmp)) == NULL)
|
if ((t = fts_open(argv, ftsoptions, dcmp)) == NULL)
|
||||||
mtree_err("fts_open: %s", strerror(errno));
|
mtree_err("fts_open: %s", strerror(errno));
|
||||||
while ((p = fts_read(t)) != NULL) {
|
while (errno = 0, (p = fts_read(t)) != NULL) {
|
||||||
if (jflag)
|
if (jflag)
|
||||||
indent = p->fts_level * 4;
|
indent = p->fts_level * 4;
|
||||||
if (check_excludes(p->fts_name, p->fts_path)) {
|
if (check_excludes(p->fts_name, p->fts_path)) {
|
||||||
@ -173,6 +173,8 @@ cwalk(FILE *fp)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
mtree_err("fts_read: %s", strerror(errno));
|
||||||
fts_close(t);
|
fts_close(t);
|
||||||
if (sflag && keys & F_CKSUM)
|
if (sflag && keys & F_CKSUM)
|
||||||
mtree_err("%s checksum: %u", fullpath, crc_total);
|
mtree_err("%s checksum: %u", fullpath, crc_total);
|
||||||
|
@ -90,7 +90,7 @@ vwalk(void)
|
|||||||
mtree_err("fts_open: %s", strerror(errno));
|
mtree_err("fts_open: %s", strerror(errno));
|
||||||
level = root;
|
level = root;
|
||||||
specdepth = rval = 0;
|
specdepth = rval = 0;
|
||||||
while ((p = fts_read(t)) != NULL) {
|
while (errno = 0, (p = fts_read(t)) != NULL) {
|
||||||
if (check_excludes(p->fts_name, p->fts_path)) {
|
if (check_excludes(p->fts_name, p->fts_path)) {
|
||||||
fts_set(t, p, FTS_SKIP);
|
fts_set(t, p, FTS_SKIP);
|
||||||
continue;
|
continue;
|
||||||
@ -160,6 +160,8 @@ vwalk(void)
|
|||||||
}
|
}
|
||||||
fts_set(t, p, FTS_SKIP);
|
fts_set(t, p, FTS_SKIP);
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
mtree_err("fts_read: %s", strerror(errno));
|
||||||
fts_close(t);
|
fts_close(t);
|
||||||
if (sflag)
|
if (sflag)
|
||||||
warnx("%s checksum: %u", fullpath, crc_total);
|
warnx("%s checksum: %u", fullpath, crc_total);
|
||||||
|
@ -268,7 +268,7 @@ main(int argc, char *argv[])
|
|||||||
if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
|
if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
|
||||||
err(1, "fts_open");
|
err(1, "fts_open");
|
||||||
|
|
||||||
while ((p = fts_read(fts)) != NULL) {
|
while (errno = 0, (p = fts_read(fts)) != NULL) {
|
||||||
switch (p->fts_info) {
|
switch (p->fts_info) {
|
||||||
case FTS_D: /* Ignore. */
|
case FTS_D: /* Ignore. */
|
||||||
if (ignorep(p))
|
if (ignorep(p))
|
||||||
|
@ -154,7 +154,7 @@ grep_tree(char **argv)
|
|||||||
__DECONST(char * const *, wd) : argv, fts_flags, NULL);
|
__DECONST(char * const *, wd) : argv, fts_flags, NULL);
|
||||||
if (fts == NULL)
|
if (fts == NULL)
|
||||||
err(2, "fts_open");
|
err(2, "fts_open");
|
||||||
while ((p = fts_read(fts)) != NULL) {
|
while (errno = 0, (p = fts_read(fts)) != NULL) {
|
||||||
switch (p->fts_info) {
|
switch (p->fts_info) {
|
||||||
case FTS_DNR:
|
case FTS_DNR:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -187,6 +187,8 @@ grep_tree(char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
err(2, "fts_read");
|
||||||
|
|
||||||
fts_close(fts);
|
fts_close(fts);
|
||||||
return (matched);
|
return (matched);
|
||||||
|
@ -2075,7 +2075,7 @@ handle_dir(char *dir)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((entry = fts_read(fts))) {
|
while (errno = 0, (entry = fts_read(fts))) {
|
||||||
switch(entry->fts_info) {
|
switch(entry->fts_info) {
|
||||||
case FTS_D:
|
case FTS_D:
|
||||||
case FTS_DP:
|
case FTS_DP:
|
||||||
@ -2090,6 +2090,8 @@ handle_dir(char *dir)
|
|||||||
handle_file(entry->fts_path, entry->fts_statp);
|
handle_file(entry->fts_path, entry->fts_statp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
warn("error with fts_read %s", dir);
|
||||||
(void)fts_close(fts);
|
(void)fts_close(fts);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -177,7 +177,7 @@ main(int argc, char **argv)
|
|||||||
if ((ftsp = fts_open(++argv, fts_options, NULL)) == NULL)
|
if ((ftsp = fts_open(++argv, fts_options, NULL)) == NULL)
|
||||||
err(1, NULL);
|
err(1, NULL);
|
||||||
|
|
||||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
for (rval = 0; errno = 0, (p = fts_read(ftsp)) != NULL;) {
|
||||||
int atflag;
|
int atflag;
|
||||||
|
|
||||||
if ((fts_options & FTS_LOGICAL) ||
|
if ((fts_options & FTS_LOGICAL) ||
|
||||||
|
@ -151,7 +151,7 @@ main(int argc, char *argv[])
|
|||||||
arg[0] = *argv;
|
arg[0] = *argv;
|
||||||
if ((ftsp = fts_open(arg, FTS_LOGICAL, NULL)) == NULL)
|
if ((ftsp = fts_open(arg, FTS_LOGICAL, NULL)) == NULL)
|
||||||
err(2, "fts_open");
|
err(2, "fts_open");
|
||||||
while ((f = fts_read(ftsp)) != NULL)
|
while (errno = 0, (f = fts_read(ftsp)) != NULL)
|
||||||
switch (f->fts_info) {
|
switch (f->fts_info) {
|
||||||
case FTS_DC:
|
case FTS_DC:
|
||||||
rval = fail(f->fts_path, "Directory causes a cycle");
|
rval = fail(f->fts_path, "Directory causes a cycle");
|
||||||
|
@ -102,7 +102,7 @@ cwalk(void)
|
|||||||
argv[1] = NULL;
|
argv[1] = NULL;
|
||||||
if ((t = fts_open(argv, ftsoptions, dsort)) == NULL)
|
if ((t = fts_open(argv, ftsoptions, dsort)) == NULL)
|
||||||
err(1, "fts_open()");
|
err(1, "fts_open()");
|
||||||
while ((p = fts_read(t))) {
|
while (errno = 0, (p = fts_read(t))) {
|
||||||
if (iflag)
|
if (iflag)
|
||||||
indent = p->fts_level * 4;
|
indent = p->fts_level * 4;
|
||||||
if (check_excludes(p->fts_name, p->fts_path)) {
|
if (check_excludes(p->fts_name, p->fts_path)) {
|
||||||
@ -137,6 +137,8 @@ cwalk(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
err(1, "fts_read()");
|
||||||
(void)fts_close(t);
|
(void)fts_close(t);
|
||||||
if (sflag && keys & F_CKSUM)
|
if (sflag && keys & F_CKSUM)
|
||||||
warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
|
warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
|
||||||
|
@ -86,7 +86,7 @@ vwalk(void)
|
|||||||
err(1, "line %d: fts_open", lineno);
|
err(1, "line %d: fts_open", lineno);
|
||||||
level = root;
|
level = root;
|
||||||
specdepth = rval = 0;
|
specdepth = rval = 0;
|
||||||
while ((p = fts_read(t))) {
|
while (errno = 0, (p = fts_read(t))) {
|
||||||
if (check_excludes(p->fts_name, p->fts_path)) {
|
if (check_excludes(p->fts_name, p->fts_path)) {
|
||||||
fts_set(t, p, FTS_SKIP);
|
fts_set(t, p, FTS_SKIP);
|
||||||
continue;
|
continue;
|
||||||
@ -149,6 +149,8 @@ vwalk(void)
|
|||||||
}
|
}
|
||||||
(void)fts_set(t, p, FTS_SKIP);
|
(void)fts_set(t, p, FTS_SKIP);
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
err(1, "fts_read()");
|
||||||
(void)fts_close(t);
|
(void)fts_close(t);
|
||||||
if (sflag)
|
if (sflag)
|
||||||
warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
|
warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
|
||||||
|
@ -142,7 +142,7 @@ main(int argc, char **argv)
|
|||||||
fts = fts_open(argv, hflag | xflag, NULL);
|
fts = fts_open(argv, hflag | xflag, NULL);
|
||||||
if (fts == NULL)
|
if (fts == NULL)
|
||||||
err(1, "cannot traverse filesystem%s", argc ? "s" : "");
|
err(1, "cannot traverse filesystem%s", argc ? "s" : "");
|
||||||
while ((ftsent = fts_read(fts)) != NULL) {
|
while (errno = 0, (ftsent = fts_read(fts)) != NULL) {
|
||||||
switch (ftsent->fts_info) {
|
switch (ftsent->fts_info) {
|
||||||
case FTS_DP: /* skip post-order */
|
case FTS_DP: /* skip post-order */
|
||||||
break;
|
break;
|
||||||
@ -176,6 +176,8 @@ main(int argc, char **argv)
|
|||||||
ftsent->fts_info, ftsent->fts_path);
|
ftsent->fts_info, ftsent->fts_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (errno != 0)
|
||||||
|
err(1, "fts_read");
|
||||||
fts_close(fts);
|
fts_close(fts);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user