if (fts_palloc(sp, (size_t)dp->d_namlen)) {
if (fts_palloc(sp, dp->d_namlen +len + 1)) {
fts_build(sp, type)	register FTS *sp;	int type;{	register struct dirent *dp;	register FTSENT *p, *head;	register int nitems;	FTSENT *cur, *tail;	DIR *dirp;	void *oldaddr;	int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno,	    nostat, doadjust;	char *cp;	/* Set current node pointer. */	cur = sp->fts_cur;	/*	 * Open the directory for reading.  If this fails, we're done.	 * If being called from fts_read, set the fts_info field.	 */#ifdef FTS_WHITEOUT	if (ISSET(FTS_WHITEOUT))		oflag = DTF_NODUP|DTF_REWIND;	else		oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;#else#define __opendir2(path, flag) opendir(path)#endif	if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {		if (type == BREAD) {			cur->fts_info = FTS_DNR;			cur->fts_errno = errno;		}		return (NULL);	}	/*	 * Nlinks is the number of possible entries of type directory in the	 * directory if we're cheating on stat calls, 0 if we're not doing	 * any stat calls at all, -1 if we're doing stats on everything.	 */	if (type == BNAMES)		nlinks = 0;	else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {		nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);		nostat = 1;	} else {		nlinks = -1;		nostat = 0;	}#ifdef notdef	(void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);	(void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",	    ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));#endif	/*	 * If we're going to need to stat anything or we want to descend	 * and stay in the directory, chdir.  If this fails we keep going,	 * but set a flag so we don't chdir after the post-order visit.	 * We won't be able to stat anything, but we can still return the	 * names themselves.  Note, that since fts_read won't be able to	 * chdir into the directory, it will have to return different path	 * names than before, i.e. "a/b" instead of "b".  Since the node	 * has already been visited in pre-order, have to wait until the	 * post-order visit to return the error.  There is a special case	 * here, if there was nothing to stat then it's not an error to	 * not be able to stat.  This is all fairly nasty.  If a program	 * needed sorted entries or stat information, they had better be	 * checking FTS_NS on the returned nodes.	 */	cderrno = 0;	if (nlinks || type == BREAD) {		if (fts_safe_changedir(sp, cur, dirfd(dirp))) {			if (nlinks && type == BREAD)				cur->fts_errno = errno;			cur->fts_flags |= FTS_DONTCHDIR;			descend = 0;			cderrno = errno;			(void)closedir(dirp);			dirp = NULL;		} else			descend = 1;	} else		descend = 0;	/*	 * Figure out the max file name length that can be stored in the	 * current path -- the inner loop allocates more path as necessary.	 * We really wouldn't have to do the maxlen calculations here, we	 * could do them in fts_read before returning the path, but it's a	 * lot easier here since the length is part of the dirent structure.	 *	 * If not changing directories set a pointer so that can just append	 * each new name into the path.	 */	maxlen = sp->fts_pathlen - cur->fts_pathlen - 1;	len = NAPPEND(cur);	if (ISSET(FTS_NOCHDIR)) {		cp = sp->fts_path + len;		*cp++ = '/';	}	level = cur->fts_level + 1;	/* Read the directory, attaching each entry to the `link' pointer. */	doadjust = 0;	for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {		if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))			continue;		if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL)			goto mem1;		if (dp->d_namlen > maxlen) {			oldaddr = sp->fts_path;			if (fts_palloc(sp, (size_t)dp->d_namlen)) {				/*				 * No more memory for path or structures.  Save				 * errno, free up the current structure and the				 * structures already allocated.				 */mem1:				saved_errno = errno;				if (p)					free(p);				fts_lfree(head);				(void)closedir(dirp);				errno = saved_errno;				cur->fts_info = FTS_ERR;				SET(FTS_STOP);				return (NULL);			}			/* Did realloc() change the pointer? */			if (oldaddr != sp->fts_path)				doadjust = 1;			maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1;		}		p->fts_pathlen = len + dp->d_namlen + 1;		p->fts_parent = sp->fts_cur;		p->fts_level = level;#ifdef FTS_WHITEOUT		if (dp->d_type == DT_WHT)			p->fts_flags |= FTS_ISW;#endif		if (cderrno) {			if (nlinks) {				p->fts_info = FTS_NS;				p->fts_errno = cderrno;			} else				p->fts_info = FTS_NSOK;			p->fts_accpath = cur->fts_accpath;		} else if (nlinks == 0#ifdef DT_DIR		    || (nostat &&		    dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)#endif		    ) {			p->fts_accpath =			    ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;			p->fts_info = FTS_NSOK;		} else {			/* Build a file name for fts_stat to stat. */			if (ISSET(FTS_NOCHDIR)) {				p->fts_accpath = p->fts_path;				memmove(cp, p->fts_name, p->fts_namelen + 1);			} else				p->fts_accpath = p->fts_name;			/* Stat it. */			p->fts_info = fts_stat(sp, p, 0);			/* Decrement link count if applicable. */			if (nlinks > 0 && (p->fts_info == FTS_D ||			    p->fts_info == FTS_DC || p->fts_info == FTS_DOT))				--nlinks;		}		/* We walk in directory order so "ls -f" doesn't get upset. */		p->fts_link = NULL;		if (head == NULL)			head = tail = p;		else {			tail->fts_link = p;			tail = p;		}		++nitems;	}	if (dirp)		(void)closedir(dirp);	/*	 * If realloc() changed the address of the path, adjust the	 * addresses for the rest of the tree and the dir list.	 */	if (doadjust)		fts_padjust(sp, head);	/*	 * If not changing directories, reset the path back to original	 * state.	 */	if (ISSET(FTS_NOCHDIR)) {		if (len == sp->fts_pathlen || nitems == 0)			--cp;		*cp = '\0';	}	/*	 * If descended after called from fts_children or after called from	 * fts_read and nothing found, get back.  At the root level we use	 * the saved fd; if one of fts_open()'s arguments is a relative path	 * to an empty directory, we wind up here with no other way back.  If	 * can't get back, we're done.	 */	if (descend && (type == BCHILD || !nitems) &&	    (cur->fts_level == FTS_ROOTLEVEL ?	    FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {		cur->fts_info = FTS_ERR;		SET(FTS_STOP);		return (NULL);	}	/* If didn't find anything, return NULL. */	if (!nitems) {		if (type == BREAD)			cur->fts_info = FTS_DP;		return (NULL);	}	/* Sort the entries. */	if (sp->fts_compar && nitems > 1)		head = fts_sort(sp, head, nitems);	return (head);}