aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Drewery <bdrewery@FreeBSD.org>2020-12-08 23:38:26 +0000
committerBryan Drewery <bdrewery@FreeBSD.org>2020-12-08 23:38:26 +0000
commit2dfa4b66b3d0caaaae6ce2df476b5615f8415a19 (patch)
tree550fa72fe4f1d83dfdc72e6db29170e0e6940f77
parentf1b18a668deb2aab9e2da908a403d58bce029d80 (diff)
downloadsrc-2dfa4b66b3d0caaaae6ce2df476b5615f8415a19.tar.gz
src-2dfa4b66b3d0caaaae6ce2df476b5615f8415a19.zip
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
Notes
Notes: svn path=/head/; revision=368467
-rw-r--r--bin/chflags/chflags.c2
-rw-r--r--bin/chmod/chmod.c2
-rw-r--r--bin/cp/cp.c3
-rw-r--r--bin/ls/ls.c2
-rw-r--r--bin/rm/rm.c2
-rw-r--r--bin/setfacl/setfacl.c4
-rw-r--r--contrib/mtree/create.c4
-rw-r--r--contrib/mtree/verify.c4
-rw-r--r--usr.bin/du/du.c2
-rw-r--r--usr.bin/grep/util.c4
-rw-r--r--usr.bin/gzip/gzip.c4
-rw-r--r--usr.sbin/chown/chown.c2
-rw-r--r--usr.sbin/ckdist/ckdist.c2
-rw-r--r--usr.sbin/fmtree/create.c4
-rw-r--r--usr.sbin/fmtree/verify.c4
-rw-r--r--usr.sbin/setfmac/setfmac.c4
16 files changed, 33 insertions, 16 deletions
diff --git a/bin/chflags/chflags.c b/bin/chflags/chflags.c
index c1d9c18b9b6b..55dedfce53f1 100644
--- a/bin/chflags/chflags.c
+++ b/bin/chflags/chflags.c
@@ -163,7 +163,7 @@ main(int argc, char *argv[])
if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL)
err(1, NULL);
- for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ for (rval = 0; errno = 0, (p = fts_read(ftsp)) != NULL;) {
int atflag;
if ((fts_options & FTS_LOGICAL) ||
diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c
index 07b7c37312d5..e8657af0d97b 100644
--- a/bin/chmod/chmod.c
+++ b/bin/chmod/chmod.c
@@ -164,7 +164,7 @@ done: argv += optind;
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
err(1, "fts_open");
- for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ for (rval = 0; errno = 0, (p = fts_read(ftsp)) != NULL;) {
int atflag;
if ((fts_options & FTS_LOGICAL) ||
diff --git a/bin/cp/cp.c b/bin/cp/cp.c
index 6c9a57d30d78..3a23394df35d 100644
--- a/bin/cp/cp.c
+++ b/bin/cp/cp.c
@@ -282,7 +282,8 @@ copy(char *argv[], enum op type, int fts_options)
if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
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) {
case FTS_NS:
case FTS_DNR:
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
index 7378268867ef..b0fe8d79e3ea 100644
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -645,7 +645,7 @@ traverse(int argc, char *argv[], int options)
ch_options = !f_recursive && !f_label &&
options & FTS_NOSTAT ? FTS_NAMEONLY : 0;
- while ((p = fts_read(ftsp)) != NULL)
+ while (errno = 0, (p = fts_read(ftsp)) != NULL)
switch (p->fts_info) {
case FTS_DC:
warnx("%s: directory causes a cycle", p->fts_name);
diff --git a/bin/rm/rm.c b/bin/rm/rm.c
index 30eb3501eb2c..111f4a1326c4 100644
--- a/bin/rm/rm.c
+++ b/bin/rm/rm.c
@@ -207,7 +207,7 @@ rm_tree(char **argv)
return;
err(1, "fts_open");
}
- while ((p = fts_read(fts)) != NULL) {
+ while (errno = 0, (p = fts_read(fts)) != NULL) {
switch (p->fts_info) {
case FTS_DNR:
if (!fflag || p->fts_errno != ENOENT) {
diff --git a/bin/setfacl/setfacl.c b/bin/setfacl/setfacl.c
index 7b0d617812dc..033f9d2572ca 100644
--- a/bin/setfacl/setfacl.c
+++ b/bin/setfacl/setfacl.c
@@ -498,8 +498,10 @@ main(int argc, char *argv[])
/* Open all files. */
if ((ftsp = fts_open(files_list, fts_options | FTS_NOSTAT, 0)) == NULL)
err(1, "fts_open");
- while ((file = fts_read(ftsp)) != NULL)
+ while (errno = 0, (file = fts_read(ftsp)) != NULL)
carried_error += handle_file(ftsp, file);
+ if (errno != 0)
+ err(1, "fts_read");
return (carried_error);
}
diff --git a/contrib/mtree/create.c b/contrib/mtree/create.c
index dc3af7447a39..7a09a1cc3951 100644
--- a/contrib/mtree/create.c
+++ b/contrib/mtree/create.c
@@ -129,7 +129,7 @@ cwalk(FILE *fp)
if ((t = fts_open(argv, ftsoptions, dcmp)) == NULL)
mtree_err("fts_open: %s", strerror(errno));
- while ((p = fts_read(t)) != NULL) {
+ while (errno = 0, (p = fts_read(t)) != NULL) {
if (jflag)
indent = p->fts_level * 4;
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);
if (sflag && keys & F_CKSUM)
mtree_err("%s checksum: %u", fullpath, crc_total);
diff --git a/contrib/mtree/verify.c b/contrib/mtree/verify.c
index 66b020ac8b9f..4aca42c52aea 100644
--- a/contrib/mtree/verify.c
+++ b/contrib/mtree/verify.c
@@ -90,7 +90,7 @@ vwalk(void)
mtree_err("fts_open: %s", strerror(errno));
level = root;
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)) {
fts_set(t, p, FTS_SKIP);
continue;
@@ -160,6 +160,8 @@ vwalk(void)
}
fts_set(t, p, FTS_SKIP);
}
+ if (errno != 0)
+ mtree_err("fts_read: %s", strerror(errno));
fts_close(t);
if (sflag)
warnx("%s checksum: %u", fullpath, crc_total);
diff --git a/usr.bin/du/du.c b/usr.bin/du/du.c
index 2365e19a67e9..012e439bba34 100644
--- a/usr.bin/du/du.c
+++ b/usr.bin/du/du.c
@@ -268,7 +268,7 @@ main(int argc, char *argv[])
if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
err(1, "fts_open");
- while ((p = fts_read(fts)) != NULL) {
+ while (errno = 0, (p = fts_read(fts)) != NULL) {
switch (p->fts_info) {
case FTS_D: /* Ignore. */
if (ignorep(p))
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 33afe4d6b030..e517e4eaee6d 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -154,7 +154,7 @@ grep_tree(char **argv)
__DECONST(char * const *, wd) : argv, fts_flags, NULL);
if (fts == NULL)
err(2, "fts_open");
- while ((p = fts_read(fts)) != NULL) {
+ while (errno = 0, (p = fts_read(fts)) != NULL) {
switch (p->fts_info) {
case FTS_DNR:
/* FALLTHROUGH */
@@ -187,6 +187,8 @@ grep_tree(char **argv)
break;
}
}
+ if (errno != 0)
+ err(2, "fts_read");
fts_close(fts);
return (matched);
diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c
index 47cfd225b844..5128e7ed43e0 100644
--- a/usr.bin/gzip/gzip.c
+++ b/usr.bin/gzip/gzip.c
@@ -2075,7 +2075,7 @@ handle_dir(char *dir)
return;
}
- while ((entry = fts_read(fts))) {
+ while (errno = 0, (entry = fts_read(fts))) {
switch(entry->fts_info) {
case FTS_D:
case FTS_DP:
@@ -2090,6 +2090,8 @@ handle_dir(char *dir)
handle_file(entry->fts_path, entry->fts_statp);
}
}
+ if (errno != 0)
+ warn("error with fts_read %s", dir);
(void)fts_close(fts);
}
#endif
diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c
index 8f09b62d10ca..a3fe5d351320 100644
--- a/usr.sbin/chown/chown.c
+++ b/usr.sbin/chown/chown.c
@@ -177,7 +177,7 @@ main(int argc, char **argv)
if ((ftsp = fts_open(++argv, fts_options, NULL)) == NULL)
err(1, NULL);
- for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ for (rval = 0; errno = 0, (p = fts_read(ftsp)) != NULL;) {
int atflag;
if ((fts_options & FTS_LOGICAL) ||
diff --git a/usr.sbin/ckdist/ckdist.c b/usr.sbin/ckdist/ckdist.c
index 22bd04819d1e..d3a0bc313a5f 100644
--- a/usr.sbin/ckdist/ckdist.c
+++ b/usr.sbin/ckdist/ckdist.c
@@ -151,7 +151,7 @@ main(int argc, char *argv[])
arg[0] = *argv;
if ((ftsp = fts_open(arg, FTS_LOGICAL, NULL)) == NULL)
err(2, "fts_open");
- while ((f = fts_read(ftsp)) != NULL)
+ while (errno = 0, (f = fts_read(ftsp)) != NULL)
switch (f->fts_info) {
case FTS_DC:
rval = fail(f->fts_path, "Directory causes a cycle");
diff --git a/usr.sbin/fmtree/create.c b/usr.sbin/fmtree/create.c
index 204f40abc15c..edfb09ebd2f2 100644
--- a/usr.sbin/fmtree/create.c
+++ b/usr.sbin/fmtree/create.c
@@ -102,7 +102,7 @@ cwalk(void)
argv[1] = NULL;
if ((t = fts_open(argv, ftsoptions, dsort)) == NULL)
err(1, "fts_open()");
- while ((p = fts_read(t))) {
+ while (errno = 0, (p = fts_read(t))) {
if (iflag)
indent = p->fts_level * 4;
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);
if (sflag && keys & F_CKSUM)
warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
diff --git a/usr.sbin/fmtree/verify.c b/usr.sbin/fmtree/verify.c
index c9291c00e218..2f9ca3dae927 100644
--- a/usr.sbin/fmtree/verify.c
+++ b/usr.sbin/fmtree/verify.c
@@ -86,7 +86,7 @@ vwalk(void)
err(1, "line %d: fts_open", lineno);
level = root;
specdepth = rval = 0;
- while ((p = fts_read(t))) {
+ while (errno = 0, (p = fts_read(t))) {
if (check_excludes(p->fts_name, p->fts_path)) {
fts_set(t, p, FTS_SKIP);
continue;
@@ -149,6 +149,8 @@ extra:
}
(void)fts_set(t, p, FTS_SKIP);
}
+ if (errno != 0)
+ err(1, "fts_read()");
(void)fts_close(t);
if (sflag)
warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
diff --git a/usr.sbin/setfmac/setfmac.c b/usr.sbin/setfmac/setfmac.c
index dd361aa2ec8b..15dc7ffc4dde 100644
--- a/usr.sbin/setfmac/setfmac.c
+++ b/usr.sbin/setfmac/setfmac.c
@@ -142,7 +142,7 @@ main(int argc, char **argv)
fts = fts_open(argv, hflag | xflag, NULL);
if (fts == NULL)
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) {
case FTS_DP: /* skip post-order */
break;
@@ -176,6 +176,8 @@ main(int argc, char **argv)
ftsent->fts_info, ftsent->fts_path);
}
}
+ if (errno != 0)
+ err(1, "fts_read");
fts_close(fts);
exit(0);
}