1. minimize code diffs with FreeBSD
2. return ENAMETOOLONG instead of ENOMEM if name is too long to fit. 3. only decrement cp if we are pointing to the end of the string. [this fixes the cp truncation of the last char problem reported]
This commit is contained in:
parent
c9370bf9e5
commit
a109c1ee32
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: fts.c,v 1.26 2005/10/22 20:55:13 christos Exp $ */
|
/* $NetBSD: fts.c,v 1.27 2005/11/17 19:13:20 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990, 1993, 1994
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: fts.c,v 1.26 2005/10/22 20:55:13 christos Exp $");
|
__RCSID("$NetBSD: fts.c,v 1.27 2005/11/17 19:13:20 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* LIBC_SCCS and not lint */
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ fts_close(sp)
|
||||||
FTS *sp;
|
FTS *sp;
|
||||||
{
|
{
|
||||||
FTSENT *freep, *p;
|
FTSENT *freep, *p;
|
||||||
int saved_errno = 0;
|
int saved_errno;
|
||||||
|
|
||||||
_DIAGASSERT(sp != NULL);
|
_DIAGASSERT(sp != NULL);
|
||||||
|
|
||||||
|
@ -270,20 +270,19 @@ fts_close(sp)
|
||||||
|
|
||||||
/* Return to original directory, save errno if necessary. */
|
/* Return to original directory, save errno if necessary. */
|
||||||
if (!ISSET(FTS_NOCHDIR)) {
|
if (!ISSET(FTS_NOCHDIR)) {
|
||||||
if (fchdir(sp->fts_rfd))
|
saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
|
||||||
saved_errno = errno;
|
|
||||||
(void)close(sp->fts_rfd);
|
(void)close(sp->fts_rfd);
|
||||||
|
/* Set errno and return. */
|
||||||
|
if (saved_errno) {
|
||||||
|
errno = saved_errno;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free up the stream pointer. */
|
/* Free up the stream pointer. */
|
||||||
free(sp);
|
free(sp);
|
||||||
/* ISSET() is illegal after this, since the macro touches sp */
|
/* ISSET() is illegal after this, since the macro touches sp */
|
||||||
|
|
||||||
/* Set errno and return. */
|
|
||||||
if (saved_errno) {
|
|
||||||
errno = saved_errno;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +612,9 @@ fts_build(sp, type)
|
||||||
size_t nitems;
|
size_t nitems;
|
||||||
FTSENT *cur, *tail;
|
FTSENT *cur, *tail;
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
int adjust, cderrno, descend, len, level, nlinks, saved_errno, nostat;
|
void *oldaddr;
|
||||||
|
size_t dnamlen;
|
||||||
|
int cderrno, descend, len, level, nlinks, saved_errno, nostat, doadjust;
|
||||||
size_t maxlen;
|
size_t maxlen;
|
||||||
#ifdef FTS_WHITEOUT
|
#ifdef FTS_WHITEOUT
|
||||||
int oflag;
|
int oflag;
|
||||||
|
@ -715,22 +716,22 @@ fts_build(sp, type)
|
||||||
level = cur->fts_level + 1;
|
level = cur->fts_level + 1;
|
||||||
|
|
||||||
/* Read the directory, attaching each entry to the `link' pointer. */
|
/* Read the directory, attaching each entry to the `link' pointer. */
|
||||||
adjust = 0;
|
doadjust = 0;
|
||||||
for (head = tail = NULL, nitems = 0; (dp = readdir(dirp)) != NULL;) {
|
for (head = tail = NULL, nitems = 0; (dp = readdir(dirp)) != NULL;) {
|
||||||
size_t dlen;
|
|
||||||
|
|
||||||
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
|
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if HAVE_STRUCT_DIRENT_D_NAMLEN
|
#if HAVE_STRUCT_DIRENT_D_NAMLEN
|
||||||
dlen = dp->d_namlen;
|
dnamlen = dp->d_namlen;
|
||||||
#else
|
#else
|
||||||
dlen = strlen(dp->d_name);
|
dnamlen = strlen(dp->d_name);
|
||||||
#endif
|
#endif
|
||||||
if ((p = fts_alloc(sp, dp->d_name, dlen)) == NULL)
|
if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL)
|
||||||
goto mem1;
|
goto mem1;
|
||||||
if (dlen >= maxlen) { /* include space for NUL */
|
if (dnamlen >= maxlen) { /* include space for NUL */
|
||||||
if (fts_palloc(sp, len + dlen + 1)) {
|
oldaddr = sp->fts_path;
|
||||||
|
if (fts_palloc(sp, dnamlen + len + 1)) {
|
||||||
/*
|
/*
|
||||||
* No more memory for path or structures. Save
|
* No more memory for path or structures. Save
|
||||||
* errno, free up the current structure and the
|
* errno, free up the current structure and the
|
||||||
|
@ -746,15 +747,33 @@ mem1: saved_errno = errno;
|
||||||
SET(FTS_STOP);
|
SET(FTS_STOP);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
adjust = 1;
|
/* Did realloc() change the pointer? */
|
||||||
if (ISSET(FTS_NOCHDIR))
|
if (oldaddr != sp->fts_path) {
|
||||||
cp = sp->fts_path + len;
|
doadjust = 1;
|
||||||
|
if (ISSET(FTS_NOCHDIR))
|
||||||
|
cp = sp->fts_path + len;
|
||||||
|
}
|
||||||
maxlen = sp->fts_pathlen - len;
|
maxlen = sp->fts_pathlen - len;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->fts_pathlen = len + dlen;
|
if (len + dnamlen >= USHRT_MAX) {
|
||||||
p->fts_parent = sp->fts_cur;
|
/*
|
||||||
|
* In an FTSENT, fts_pathlen is a u_short so it is
|
||||||
|
* possible to wraparound here. If we do, free up
|
||||||
|
* the current structure and the structures already
|
||||||
|
* allocated, then error out with ENAMETOOLONG.
|
||||||
|
*/
|
||||||
|
free(p);
|
||||||
|
fts_lfree(head);
|
||||||
|
(void)closedir(dirp);
|
||||||
|
cur->fts_info = FTS_ERR;
|
||||||
|
SET(FTS_STOP);
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
p->fts_level = level;
|
p->fts_level = level;
|
||||||
|
p->fts_pathlen = len + dnamlen;
|
||||||
|
p->fts_parent = sp->fts_cur;
|
||||||
|
|
||||||
#ifdef FTS_WHITEOUT
|
#ifdef FTS_WHITEOUT
|
||||||
if (dp->d_type == DT_WHT)
|
if (dp->d_type == DT_WHT)
|
||||||
|
@ -810,7 +829,7 @@ mem1: saved_errno = errno;
|
||||||
* If had to realloc the path, adjust the addresses for the rest
|
* If had to realloc the path, adjust the addresses for the rest
|
||||||
* of the tree.
|
* of the tree.
|
||||||
*/
|
*/
|
||||||
if (adjust)
|
if (doadjust)
|
||||||
fts_padjust(sp, head);
|
fts_padjust(sp, head);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -818,7 +837,7 @@ mem1: saved_errno = errno;
|
||||||
* state.
|
* state.
|
||||||
*/
|
*/
|
||||||
if (ISSET(FTS_NOCHDIR)) {
|
if (ISSET(FTS_NOCHDIR)) {
|
||||||
if (cp - 1 > sp->fts_path)
|
if (len == sp->fts_pathlen || nitems == 0)
|
||||||
--cp;
|
--cp;
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1107,7 @@ fts_palloc(sp, size)
|
||||||
#if 1
|
#if 1
|
||||||
/* Protect against fts_pathlen overflow. */
|
/* Protect against fts_pathlen overflow. */
|
||||||
if (size > USHRT_MAX + 1) {
|
if (size > USHRT_MAX + 1) {
|
||||||
errno = ENOMEM;
|
errno = ENAMETOOLONG;
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue