diff options
author | Jim Meyering <jim@meyering.net> | 2004-10-13 19:25:30 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2004-10-13 19:25:30 +0000 |
commit | 8be7fa2d6ac5ea7d5dbffc1a165c797b6e53586e (patch) | |
tree | 95d77389a2df2bddebff49bcd1a004ca2fc4cecb | |
parent | 292abe4bf00a18027082658a68315ae5581dfaea (diff) | |
download | coreutils-8be7fa2d6ac5ea7d5dbffc1a165c797b6e53586e.tar.xz |
(fts_read): When about to fail (by returning NULL) due
to a failed fchdir or failed fts_safe_changedir call, set
`sp->fts_cur = p'. Do this by removing the explicit `return NULL;'
statements and setting p->fts_errno so execution falls through
to the common-case code below. Otherwise, after such a failure,
calling fts_close would attempt to free an already-freed buffer.
Reported by Luis Lopez Lopez in http://bugs.debian.org/276352.
-rw-r--r-- | lib/fts.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -716,27 +716,28 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { + p->fts_errno = errno; SET(FTS_STOP); - return (NULL); } } else if (p->fts_flags & FTS_SYMFOLLOW) { if (FCHDIR(sp, p->fts_symfd)) { saved_errno = errno; (void)close(p->fts_symfd); __set_errno (saved_errno); + p->fts_errno = errno; SET(FTS_STOP); - return (NULL); } (void)close(p->fts_symfd); } else if (!(p->fts_flags & FTS_DONTCHDIR) && fts_safe_changedir(sp, p->fts_parent, -1, "..")) { + p->fts_errno = errno; SET(FTS_STOP); - return (NULL); } p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; if (p->fts_errno == 0) LEAVE_DIR (sp, p, "3"); - return (sp->fts_cur = p); + sp->fts_cur = p; + return ISSET(FTS_STOP) ? NULL : p; } /* |