diff options
| -rw-r--r-- | meta/recipes-core/fts/fts.bb | 36 | ||||
| -rw-r--r-- | meta/recipes-core/fts/fts/fts-header-correctness.patch | 25 | ||||
| -rw-r--r-- | meta/recipes-core/fts/fts/fts-uclibc.patch | 50 | ||||
| -rw-r--r-- | meta/recipes-core/fts/fts/gcc5.patch | 1368 | ||||
| -rw-r--r-- | meta/recipes-core/fts/fts/remove_cdefs.patch | 69 | ||||
| -rw-r--r-- | meta/recipes-core/fts/fts/stdint.patch | 15 | 
6 files changed, 8 insertions, 1555 deletions
| diff --git a/meta/recipes-core/fts/fts.bb b/meta/recipes-core/fts/fts.bb index de9297ebed..02f54086a3 100644 --- a/meta/recipes-core/fts/fts.bb +++ b/meta/recipes-core/fts/fts.bb @@ -3,38 +3,18 @@  SUMMARY = "POSIX file tree stream operations library"  HOMEPAGE = "https://sites.google.com/a/bostic.com/keithbostic" -LICENSE = "BSD-4-Clause" -LIC_FILES_CHKSUM = "file://fts.h;beginline=1;endline=36;md5=2532eddb3d1a21905723a4011ec4e085" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://COPYING;md5=5ffe358174aad383f1b69ce3b53da982"  SECTION = "libs" -SRC_URI = "https://sites.google.com/a/bostic.com/keithbostic/files/fts.tar.gz \ -           file://fts-header-correctness.patch \ -           file://fts-uclibc.patch \ -           file://remove_cdefs.patch \ -           file://stdint.patch \ -           file://gcc5.patch \ -" - -SRC_URI[md5sum] = "120c14715485ec6ced14f494d059d20a" -SRC_URI[sha256sum] = "3df9b9b5a45aeaf16f33bb84e692a10dc662e22ec8a51748f98767d67fb6f342" - -S = "${WORKDIR}/${BPN}" +SRCREV = "944333aed9dc24cfa76cc64bfe70c75d25652753" +PV = "1.2+git${SRCPV}" -do_configure[noexec] = "1" - -HASHSTYLE_mipsarch = "sysv" -HASHSTYLE = "gnu" - -VER = "0" -do_compile () { -    ${CC} -I${S} -fPIC -shared -Wl,--hash-style=${HASHSTYLE} -o libfts.so.${VER} -Wl,-soname,libfts.so.${VER} ${S}/fts.c -} +SRC_URI = "git://github.com/voidlinux/musl-fts \ +" +S = "${WORKDIR}/git" -do_install() { -    install -Dm755 ${B}/libfts.so.${VER} ${D}${libdir}/libfts.so.${VER} -    ln -sf libfts.so.${VER} ${D}${libdir}/libfts.so -    install -Dm644 ${S}/fts.h ${D}${includedir}/fts.h -} +inherit autotools pkgconfig  #  # We will skip parsing for non-musl systems  # diff --git a/meta/recipes-core/fts/fts/fts-header-correctness.patch b/meta/recipes-core/fts/fts/fts-header-correctness.patch deleted file mode 100644 index c73ddc95d8..0000000000 --- a/meta/recipes-core/fts/fts/fts-header-correctness.patch +++ /dev/null @@ -1,25 +0,0 @@ -Included needed headers for compiling with musl - -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Upstream-Status: Inappropriate - ---- fts.orig/fts.h -+++ fts/fts.h -@@ -38,6 +38,17 @@ - #ifndef	_FTS_H_ - #define	_FTS_H_ -  -+#include <sys/types.h> -+#include <sys/param.h> -+#include <sys/stat.h> -+ -+#include <dirent.h> -+#include <errno.h> -+#include <fcntl.h> -+#include <stdlib.h> -+#include <string.h> -+#include <unistd.h> -+ - typedef struct { - 	struct _ftsent *fts_cur;	/* current node */ - 	struct _ftsent *fts_child;	/* linked list of children */ diff --git a/meta/recipes-core/fts/fts/fts-uclibc.patch b/meta/recipes-core/fts/fts/fts-uclibc.patch deleted file mode 100644 index 397654bf51..0000000000 --- a/meta/recipes-core/fts/fts/fts-uclibc.patch +++ /dev/null @@ -1,50 +0,0 @@ -Add missing defines for uclibc - -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Upstream-Status: Inappropriate - ---- fts.orig/fts.c -+++ fts/fts.c -@@ -31,6 +31,10 @@ -  * SUCH DAMAGE. -  */ -  -+#define	alignof(TYPE)   ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2) -+#define	ALIGNBYTES	(alignof(long double) - 1) -+#define	ALIGN(p)	(((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)  -+ - #if defined(LIBC_SCCS) && !defined(lint) - static char sccsid[] = "@(#)fts.c	8.6 (Berkeley) 8/14/94"; - #endif /* LIBC_SCCS and not lint */ -@@ -652,10 +656,10 @@ - 		if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) - 			continue; -  --		if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL) -+		if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_reclen)) == NULL) - 			goto mem1; --		if (dp->d_namlen > maxlen) { --			if (fts_palloc(sp, (size_t)dp->d_namlen)) { -+		if (dp->d_reclen > maxlen) { -+			if (fts_palloc(sp, (size_t)dp->d_reclen)) { - 				/* - 				 * No more memory for path or structures.  Save - 				 * errno, free up the current structure and the -@@ -675,7 +679,7 @@ - 			maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1; - 		} -  --		p->fts_pathlen = len + dp->d_namlen + 1; -+		p->fts_pathlen = len + dp->d_reclen + 1; - 		p->fts_parent = sp->fts_cur; - 		p->fts_level = level; -  -@@ -784,7 +788,7 @@ - 	/* If user needs stat info, stat buffer already allocated. */ - 	sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; -  --#ifdef DT_WHT -+#ifdef S_IFWHT - 	/* - 	 * Whited-out files don't really exist.  However, there's stat(2) file - 	 * mask for them, so we set it so that programs (i.e., find) don't have diff --git a/meta/recipes-core/fts/fts/gcc5.patch b/meta/recipes-core/fts/fts/gcc5.patch deleted file mode 100644 index f5b948edc0..0000000000 --- a/meta/recipes-core/fts/fts/gcc5.patch +++ /dev/null @@ -1,1368 +0,0 @@ -Forward port the sources to be able to compile with c99/gcc5 - -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Upstream-Status: Inappropriate - -Index: fts/fts.c -=================================================================== ---- fts.orig/fts.c -+++ fts/fts.c -@@ -51,16 +51,6 @@ static char sccsid[] = "@(#)fts.c	8.6 (B - #include <string.h> - #include <unistd.h> -  --static FTSENT	*fts_alloc __P(FTS *, char *, int); --static FTSENT	*fts_build __P(FTS *, int); --static void	 fts_lfree __P(FTSENT *); --static void	 fts_load __P(FTS *, FTSENT *); --static size_t	 fts_maxarglen __P(char * const *); --static void	 fts_padjust __P(FTS *, void *); --static int	 fts_palloc __P(FTS *, size_t); --static FTSENT	*fts_sort __P(FTS *, FTSENT *, int); --static u_short	 fts_stat __P(FTS *, struct dirent *, FTSENT *, int); -- - #define	ISDOT(a)	(a[0] == '.' && (!a[1] || a[1] == '.' && !a[2])) -  - #define	ISSET(opt)	(sp->fts_options & opt) -@@ -73,119 +63,16 @@ static u_short	 fts_stat __P(FTS *, stru - #define	BCHILD		1		/* fts_children */ - #define	BNAMES		2		/* fts_children, names only */ - #define	BREAD		3		/* fts_read */ -- --FTS * --fts_open(argv, options, compar) --	char * const *argv; --	register int options; --	int (*compar)(); --{ --	register FTS *sp; --	register FTSENT *p, *root; --	register int nitems; --	FTSENT *parent, *tmp; --	int len; -- --	/* Options check. */ --	if (options & ~FTS_OPTIONMASK) { --		errno = EINVAL; --		return (NULL); --	} -- --	/* Allocate/initialize the stream */ --	if ((sp = malloc((u_int)sizeof(FTS))) == NULL) --		return (NULL); --	memset(sp, 0, sizeof(FTS)); --	sp->fts_compar = compar; --	sp->fts_options = options; -- --	/* Logical walks turn on NOCHDIR; symbolic links are too hard. */ --	if (ISSET(FTS_LOGICAL)) --		SET(FTS_NOCHDIR); -- --	/* --	 * Start out with 1K of path space, and enough, in any case, --	 * to hold the user's paths. --	 */ --	if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) --		goto mem1; -- --	/* Allocate/initialize root's parent. */ --	if ((parent = fts_alloc(sp, "", 0)) == NULL) --		goto mem2; --	parent->fts_level = FTS_ROOTPARENTLEVEL; -- --	/* Allocate/initialize root(s). */ --	for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) { --		/* Don't allow zero-length paths. */ --		if ((len = strlen(*argv)) == 0) { --			errno = EINVAL; --			goto mem3; --		} -- --		p = fts_alloc(sp, *argv, len); --		p->fts_level = FTS_ROOTLEVEL; --		p->fts_parent = parent; --		p->fts_accpath = p->fts_name; --		p->fts_info = fts_stat(sp, NULL, p, ISSET(FTS_COMFOLLOW)); -- --		/* Command-line "." and ".." are real directories. */ --		if (p->fts_info == FTS_DOT) --			p->fts_info = FTS_D; -- --		/* --		 * If comparison routine supplied, traverse in sorted --		 * order; otherwise traverse in the order specified. --		 */ --		if (compar) { --			p->fts_link = root; --			root = p; --		} else { --			p->fts_link = NULL; --			if (root == NULL) --				tmp = root = p; --			else { --				tmp->fts_link = p; --				tmp = p; --			} --		} --	} --	if (compar && nitems > 1) --		root = fts_sort(sp, root, nitems); -- --	/* --	 * Allocate a dummy pointer and make fts_read think that we've just --	 * finished the node before the root(s); set p->fts_info to FTS_INIT --	 * so that everything about the "current" node is ignored. --	 */ --	if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) --		goto mem3; --	sp->fts_cur->fts_link = root; --	sp->fts_cur->fts_info = FTS_INIT; -- --	/* --	 * If using chdir(2), grab a file descriptor pointing to dot to insure --	 * that we can get back here; this could be avoided for some paths, --	 * but almost certainly not worth the effort.  Slashes, symbolic links, --	 * and ".." are all fairly nasty problems.  Note, if we can't get the --	 * descriptor we run anyway, just more slowly. --	 */ --	if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0) --		SET(FTS_NOCHDIR); -- --	return (sp); -- --mem3:	fts_lfree(root); --	free(parent); --mem2:	free(sp->fts_path); --mem1:	free(sp); --	return (NULL); --} -+/* -+ * Special case a root of "/" so that slashes aren't appended which would -+ * cause paths to be written as "//foo". -+ */ -+#define	NAPPEND(p)							\ -+	(p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 &&	\ -+	    p->fts_path[0] == '/' ? 0 : p->fts_pathlen) -  - static void --fts_load(sp, p) --	FTS *sp; --	register FTSENT *p; -+fts_load(FTS *sp, register FTSENT *p) - { - 	register int len; - 	register char *cp; -@@ -208,332 +95,214 @@ fts_load(sp, p) - 	sp->fts_dev = p->fts_dev; - } -  --int --fts_close(sp) --	FTS *sp; -+static void -+fts_lfree(register FTSENT *head) - { --	register FTSENT *freep, *p; --	int saved_errno; -+	register FTSENT *p; -  --	/* --	 * This still works if we haven't read anything -- the dummy structure --	 * points to the root list, so we step through to the end of the root --	 * list which has a valid parent pointer. --	 */ --	if (sp->fts_cur) { --		for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { --			freep = p; --			p = p->fts_link ? p->fts_link : p->fts_parent; --			free(freep); --		} -+	/* Free a linked list of structures. */ -+	while (p = head) { -+		head = head->fts_link; - 		free(p); - 	} -+} -  --	/* Free up child linked list, sort array, path buffer. */ --	if (sp->fts_child) --		fts_lfree(sp->fts_child); --	if (sp->fts_array) --		free(sp->fts_array); --	free(sp->fts_path); -+static size_t -+fts_maxarglen(char * const *argv) -+{ -+	size_t len, max; -  --	/* Return to original directory, save errno if necessary. */ --	if (!ISSET(FTS_NOCHDIR)) { --		saved_errno = fchdir(sp->fts_rfd) ? errno : 0; --		(void)close(sp->fts_rfd); --	} -+	for (max = 0; *argv; ++argv) -+		if ((len = strlen(*argv)) > max) -+			max = len; -+	return (max); -+} -  --	/* Free up the stream pointer. */ --	free(sp); -  --	/* Set errno and return. */ --	if (!ISSET(FTS_NOCHDIR) && saved_errno) { --		errno = saved_errno; --		return (-1); -+/* -+ * When the path is realloc'd, have to fix all of the pointers in structures -+ * already returned. -+ */ -+static void -+fts_padjust(FTS *sp, void *addr) -+{ -+	FTSENT *p; -+ -+#define	ADJUST(p) {							\ -+	(p)->fts_accpath =						\ -+	    (char *)addr + ((p)->fts_accpath - (p)->fts_path);		\ -+	(p)->fts_path = addr;						\ -+} -+	/* Adjust the current set of children. */ -+	for (p = sp->fts_child; p; p = p->fts_link) -+		ADJUST(p); -+ -+	/* Adjust the rest of the tree. */ -+	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { -+		ADJUST(p); -+		p = p->fts_link ? p->fts_link : p->fts_parent; - 	} --	return (0); - } -  - /* -- * Special case a root of "/" so that slashes aren't appended which would -- * cause paths to be written as "//foo". -+ * Allow essentially unlimited paths; find, rm, ls should all work on any tree. -+ * Most systems will allow creation of paths much longer than MAXPATHLEN, even -+ * though the kernel won't resolve them.  Add the size (not just what's needed) -+ * plus 256 bytes so don't realloc the path 2 bytes at a time. -  */ --#define	NAPPEND(p)							\ --	(p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 &&	\ --	    p->fts_path[0] == '/' ? 0 : p->fts_pathlen) -+static int -+fts_palloc(FTS *sp, size_t more) -+{ -+	sp->fts_pathlen += more + 256; -+	sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen); -+	return (sp->fts_path == NULL); -+} -  --FTSENT * --fts_read(sp) --	register FTS *sp; -+static FTSENT * -+fts_alloc(FTS *sp, char *name, register int namelen) - { --	register FTSENT *p, *tmp; --	register int instr; --	register char *t; --	int saved_errno; -+	register FTSENT *p; -+	size_t len; -  --	/* If finished or unrecoverable error, return NULL. */ --	if (sp->fts_cur == NULL || ISSET(FTS_STOP)) -+	/* -+	 * The file name is a variable length array and no stat structure is -+	 * necessary if the user has set the nostat bit.  Allocate the FTSENT -+	 * structure, the file name and the stat structure in one chunk, but -+	 * be careful that the stat structure is reasonably aligned.  Since the -+	 * fts_name field is declared to be of size 1, the fts_name pointer is -+	 * namelen + 2 before the first possible address of the stat structure. -+	 */ -+	len = sizeof(FTSENT) + namelen; -+	if (!ISSET(FTS_NOSTAT)) -+		len += sizeof(struct stat) + ALIGNBYTES; -+	if ((p = malloc(len)) == NULL) - 		return (NULL); -  --	/* Set current node pointer. */ --	p = sp->fts_cur; -+	/* Copy the name plus the trailing NULL. */ -+	memmove(p->fts_name, name, namelen + 1); -  --	/* Save and zero out user instructions. */ --	instr = p->fts_instr; -+	if (!ISSET(FTS_NOSTAT)) -+		p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); -+	p->fts_namelen = namelen; -+	p->fts_path = sp->fts_path; -+	p->fts_errno = 0; -+	p->fts_flags = 0; - 	p->fts_instr = FTS_NOINSTR; -+	p->fts_number = 0; -+	p->fts_pointer = NULL; -+	return (p); -+} -  --	/* Any type of file may be re-visited; re-stat and re-turn. */ --	if (instr == FTS_AGAIN) { --		p->fts_info = fts_stat(sp, NULL, p, 0); --		return (p); --	} -  -+static u_short -+fts_stat(FTS *sp, register FTSENT *p, struct dirent *dp, int follow) -+{ -+	register FTSENT *t; -+	register dev_t dev; -+	register ino_t ino; -+	struct stat *sbp, sb; -+	int saved_errno; -+ -+	/* If user needs stat info, stat buffer already allocated. */ -+	sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; -+ -+#ifdef S_IFWHT - 	/* --	 * Following a symlink -- SLNONE test allows application to see --	 * SLNONE and recover.  If indirecting through a symlink, have --	 * keep a pointer to current location.  If unable to get that --	 * pointer, follow fails. --	 */ --	if (instr == FTS_FOLLOW && --	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { --		p->fts_info = fts_stat(sp, NULL, p, 1); --		if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) --			if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) { --				p->fts_errno = errno; --				p->fts_info = FTS_ERR; --			} else --				p->fts_flags |= FTS_SYMFOLLOW; --		return (p); -+	 * Whited-out files don't really exist.  However, there's stat(2) file -+	 * mask for them, so we set it so that programs (i.e., find) don't have -+	 * to test FTS_W separately from other file types. -+	 */ -+	if (dp != NULL && dp->d_type == DT_WHT) { -+		memset(sbp, 0, sizeof(struct stat)); -+		sbp->st_mode = S_IFWHT; -+		return (FTS_W); - 	} -- --	/* Directory in pre-order. */ --	if (p->fts_info == FTS_D) { --		/* If skipped or crossed mount point, do post-order visit. */ --		if (instr == FTS_SKIP || --		    ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) { --			if (p->fts_flags & FTS_SYMFOLLOW) --				(void)close(p->fts_symfd); --			if (sp->fts_child) { --				fts_lfree(sp->fts_child); --				sp->fts_child = NULL; --			} --			p->fts_info = FTS_DP; --			return (p); --		}  -- --		/* Rebuild if only read the names and now traversing. */ --		if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) { --			sp->fts_options &= ~FTS_NAMEONLY; --			fts_lfree(sp->fts_child); --			sp->fts_child = NULL; --		} -- --		/* --		 * Cd to the subdirectory. --		 * --		 * If have already read and now fail to chdir, whack the list --		 * to make the names come out right, and set the parent errno --		 * so the application will eventually get an error condition. --		 * Set the FTS_DONTCHDIR flag so that when we logically change --		 * directories back to the parent we don't do a chdir. --		 * --		 * If haven't read do so.  If the read fails, fts_build sets --		 * FTS_STOP or the fts_info field of the node. --		 */ --		if (sp->fts_child) { --			if (CHDIR(sp, p->fts_accpath)) { --				p->fts_errno = errno; --				p->fts_flags |= FTS_DONTCHDIR; --				for (p = sp->fts_child; p; p = p->fts_link) --					p->fts_accpath = --					    p->fts_parent->fts_accpath; --			} --		} else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { --			if (ISSET(FTS_STOP)) --				return (NULL); --			return (p); -+#endif -+ -+	/* -+	 * If doing a logical walk, or application requested FTS_FOLLOW, do -+	 * a stat(2).  If that fails, check for a non-existent symlink.  If -+	 * fail, set the errno from the stat call. -+	 */ -+	if (ISSET(FTS_LOGICAL) || follow) { -+		if (stat(p->fts_accpath, sbp)) { -+			saved_errno = errno; -+			if (!lstat(p->fts_accpath, sbp)) { -+				errno = 0; -+				return (FTS_SLNONE); -+			} -+			p->fts_errno = saved_errno; -+			goto err; - 		} --		p = sp->fts_child; --		sp->fts_child = NULL; --		goto name; -+	} else if (lstat(p->fts_accpath, sbp)) { -+		p->fts_errno = errno; -+err:		memset(sbp, 0, sizeof(struct stat)); -+		return (FTS_NS); - 	} -  --	/* Move to the next node on this level. */ --next:	tmp = p; --	if (p = p->fts_link) { --		free(tmp); -- --		/* --		 * If reached the top, return to the original directory, and --		 * load the paths for the next root. --		 */ --		if (p->fts_level == FTS_ROOTLEVEL) { --			if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { --				SET(FTS_STOP); --				return (NULL); --			} --			fts_load(sp, p); --			return (sp->fts_cur = p); --		} -- -+	if (S_ISDIR(sbp->st_mode)) { - 		/* --		 * User may have called fts_set on the node.  If skipped, --		 * ignore.  If followed, get a file descriptor so we can --		 * get back if necessary. -+		 * Set the device/inode.  Used to find cycles and check for -+		 * crossing mount points.  Also remember the link count, used -+		 * in fts_build to limit the number of stat calls.  It is -+		 * understood that these fields are only referenced if fts_info -+		 * is set to FTS_D. - 		 */ --		if (p->fts_instr == FTS_SKIP) --			goto next; --		if (p->fts_instr == FTS_FOLLOW) { --			p->fts_info = fts_stat(sp, NULL, p, 1); --			if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) --				if ((p->fts_symfd = --				    open(".", O_RDONLY, 0)) < 0) { --					p->fts_errno = errno; --					p->fts_info = FTS_ERR; --				} else --					p->fts_flags |= FTS_SYMFOLLOW; --			p->fts_instr = FTS_NOINSTR; --		} -- --name:		t = sp->fts_path + NAPPEND(p->fts_parent); --		*t++ = '/'; --		memmove(t, p->fts_name, p->fts_namelen + 1); --		return (sp->fts_cur = p); --	} -+		dev = p->fts_dev = sbp->st_dev; -+		ino = p->fts_ino = sbp->st_ino; -+		p->fts_nlink = sbp->st_nlink; -  --	/* Move up to the parent node. */ --	p = tmp->fts_parent; --	free(tmp); -+		if (ISDOT(p->fts_name)) -+			return (FTS_DOT); -  --	if (p->fts_level == FTS_ROOTPARENTLEVEL) { - 		/* --		 * Done; free everything up and set errno to 0 so the user --		 * can distinguish between error and EOF. -+		 * Cycle detection is done by brute force when the directory -+		 * is first encountered.  If the tree gets deep enough or the -+		 * number of symbolic links to directories is high enough, -+		 * something faster might be worthwhile. - 		 */ --		free(p); --		errno = 0; --		return (sp->fts_cur = NULL); --	} -- --	/* Nul terminate the pathname. */ --	sp->fts_path[p->fts_pathlen] = '\0'; -- --	/* --	 * Return to the parent directory.  If at a root node or came through --	 * a symlink, go back through the file descriptor.  Otherwise, cd up --	 * one directory. --	 */ --	if (p->fts_level == FTS_ROOTLEVEL) { --		if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { --			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); --			errno = saved_errno; --			SET(FTS_STOP); --			return (NULL); --		} --		(void)close(p->fts_symfd); --	} else if (!(p->fts_flags & FTS_DONTCHDIR)) { --		if (CHDIR(sp, "..")) { --			SET(FTS_STOP); --			return (NULL); --		} --	} --	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; --	return (sp->fts_cur = p); --} -- --/* -- * Fts_set takes the stream as an argument although it's not used in this -- * implementation; it would be necessary if anyone wanted to add global -- * semantics to fts using fts_set.  An error return is allowed for similar -- * reasons. -- */ --/* ARGSUSED */ --int --fts_set(sp, p, instr) --	FTS *sp; --	FTSENT *p; --	int instr; --{ --	if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && --	    instr != FTS_NOINSTR && instr != FTS_SKIP) { --		errno = EINVAL; --		return (1); -+		for (t = p->fts_parent; -+		    t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) -+			if (ino == t->fts_ino && dev == t->fts_dev) { -+				p->fts_cycle = t; -+				return (FTS_DC); -+			} -+		return (FTS_D); - 	} --	p->fts_instr = instr; --	return (0); -+	if (S_ISLNK(sbp->st_mode)) -+		return (FTS_SL); -+	if (S_ISREG(sbp->st_mode)) -+		return (FTS_F); -+	return (FTS_DEFAULT); - } -  --FTSENT * --fts_children(sp, instr) --	register FTS *sp; --	int instr; -+static FTSENT * -+fts_sort(FTS *sp, FTSENT *head, register int nitems) - { --	register FTSENT *p; --	int fd; -- --	if (instr && instr != FTS_NAMEONLY) { --		errno = EINVAL; --		return (NULL); --	} -- --	/* Set current node pointer. */ --	p = sp->fts_cur; -- --	/* --	 * Errno set to 0 so user can distinguish empty directory from --	 * an error. --	 */ --	errno = 0; -- --	/* Fatal errors stop here. */ --	if (ISSET(FTS_STOP)) --		return (NULL); -- --	/* Return logical hierarchy of user's arguments. */ --	if (p->fts_info == FTS_INIT) --		return (p->fts_link); -- --	/* --	 * If not a directory being visited in pre-order, stop here.  Could --	 * allow FTS_DNR, assuming the user has fixed the problem, but the --	 * same effect is available with FTS_AGAIN. --	 */ --	if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) --		return (NULL); -- --	/* Free up any previous child list. */ --	if (sp->fts_child) --		fts_lfree(sp->fts_child); -- --	if (instr == FTS_NAMEONLY) { --		sp->fts_options |= FTS_NAMEONLY; --		instr = BNAMES; --	} else  --		instr = BCHILD; -+	register FTSENT **ap, *p; -  - 	/* --	 * If using chdir on a relative path and called BEFORE fts_read does --	 * its chdir to the root of a traversal, we can lose -- we need to --	 * chdir into the subdirectory, and we don't know where the current --	 * directory is, so we can't get back so that the upcoming chdir by --	 * fts_read will work. -+	 * Construct an array of pointers to the structures and call qsort(3). -+	 * Reassemble the array in the order returned by qsort.  If unable to -+	 * sort for memory reasons, return the directory entries in their -+	 * current order.  Allocate enough space for the current needs plus -+	 * 40 so don't realloc one entry at a time. - 	 */ --	if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || --	    ISSET(FTS_NOCHDIR)) --		return (sp->fts_child = fts_build(sp, instr)); -- --	if ((fd = open(".", O_RDONLY, 0)) < 0) --		return (NULL); --	sp->fts_child = fts_build(sp, instr); --	if (fchdir(fd)) --		return (NULL); --	(void)close(fd); --	return (sp->fts_child); -+	if (nitems > sp->fts_nitems) { -+		sp->fts_nitems = nitems + 40; -+		if ((sp->fts_array = realloc(sp->fts_array, -+		    (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) { -+			sp->fts_nitems = 0; -+			return (head); -+		} -+	} -+	for (ap = sp->fts_array, p = head; p; p = p->fts_link) -+		*ap++ = p; -+	qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); -+	for (head = *(ap = sp->fts_array); --nitems; ++ap) -+		ap[0]->fts_link = ap[1]; -+	ap[0]->fts_link = NULL; -+	return (head); - } -  - /* -@@ -551,9 +320,7 @@ fts_children(sp, instr) -  * been found, cutting the stat calls by about 2/3. -  */ - static FTSENT * --fts_build(sp, type) --	register FTS *sp; --	int type; -+fts_build(register FTS *sp, int type) - { - 	register struct dirent *dp; - 	register FTSENT *p, *head; -@@ -716,283 +483,479 @@ mem1:				saved_errno = errno; - 				--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; -+		/* 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; -+	} -+	(void)closedir(dirp); -+ -+	/* -+	 * If had to realloc the path, adjust the addresses for the rest -+	 * of the tree. -+	 */ -+	if (adjaddr) -+		fts_padjust(sp, adjaddr); -+ -+	/* -+	 * If not changing directories, reset the path back to original -+	 * state. -+	 */ -+	if (ISSET(FTS_NOCHDIR)) { -+		if (cp - 1 > sp->fts_path) -+			--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); -+} -+ -+ -+FTS * -+fts_open(char * const *argv, register int options, int (*compar)()) -+{ -+	register FTS *sp; -+	register FTSENT *p, *root; -+	register int nitems; -+	FTSENT *parent, *tmp; -+	int len; -+ -+	/* Options check. */ -+	if (options & ~FTS_OPTIONMASK) { -+		errno = EINVAL; -+		return (NULL); -+	} -+ -+	/* Allocate/initialize the stream */ -+	if ((sp = malloc((u_int)sizeof(FTS))) == NULL) -+		return (NULL); -+	memset(sp, 0, sizeof(FTS)); -+	sp->fts_compar = compar; -+	sp->fts_options = options; -+ -+	/* Logical walks turn on NOCHDIR; symbolic links are too hard. */ -+	if (ISSET(FTS_LOGICAL)) -+		SET(FTS_NOCHDIR); -+ -+	/* -+	 * Start out with 1K of path space, and enough, in any case, -+	 * to hold the user's paths. -+	 */ -+	if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) -+		goto mem1; -+ -+	/* Allocate/initialize root's parent. */ -+	if ((parent = fts_alloc(sp, "", 0)) == NULL) -+		goto mem2; -+	parent->fts_level = FTS_ROOTPARENTLEVEL; -+ -+	/* Allocate/initialize root(s). */ -+	for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) { -+		/* Don't allow zero-length paths. */ -+		if ((len = strlen(*argv)) == 0) { -+			errno = EINVAL; -+			goto mem3; -+		} -+ -+		p = fts_alloc(sp, *argv, len); -+		p->fts_level = FTS_ROOTLEVEL; -+		p->fts_parent = parent; -+		p->fts_accpath = p->fts_name; -+		p->fts_info = fts_stat(sp, NULL, p, ISSET(FTS_COMFOLLOW)); -+ -+		/* Command-line "." and ".." are real directories. */ -+		if (p->fts_info == FTS_DOT) -+			p->fts_info = FTS_D; -+ -+		/* -+		 * If comparison routine supplied, traverse in sorted -+		 * order; otherwise traverse in the order specified. -+		 */ -+		if (compar) { -+			p->fts_link = root; -+			root = p; -+		} else { -+			p->fts_link = NULL; -+			if (root == NULL) -+				tmp = root = p; -+			else { -+				tmp->fts_link = p; -+				tmp = p; -+			} - 		} --		++nitems; - 	} --	(void)closedir(dirp); -- --	/* --	 * If had to realloc the path, adjust the addresses for the rest --	 * of the tree. --	 */ --	if (adjaddr) --		fts_padjust(sp, adjaddr); -+	if (compar && nitems > 1) -+		root = fts_sort(sp, root, nitems); -  - 	/* --	 * If not changing directories, reset the path back to original --	 * state. -+	 * Allocate a dummy pointer and make fts_read think that we've just -+	 * finished the node before the root(s); set p->fts_info to FTS_INIT -+	 * so that everything about the "current" node is ignored. - 	 */ --	if (ISSET(FTS_NOCHDIR)) { --		if (cp - 1 > sp->fts_path) --			--cp; --		*cp = '\0'; --	} -+	if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) -+		goto mem3; -+	sp->fts_cur->fts_link = root; -+	sp->fts_cur->fts_info = FTS_INIT; -  - 	/* --	 * 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 using chdir(2), grab a file descriptor pointing to dot to insure -+	 * that we can get back here; this could be avoided for some paths, -+	 * but almost certainly not worth the effort.  Slashes, symbolic links, -+	 * and ".." are all fairly nasty problems.  Note, if we can't get the -+	 * descriptor we run anyway, just more slowly. - 	 */ --	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 (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0) -+		SET(FTS_NOCHDIR); -  --	/* If didn't find anything, return NULL. */ --	if (!nitems) { --		if (type == BREAD) --			cur->fts_info = FTS_DP; --		return (NULL); --	} -+	return (sp); -  --	/* Sort the entries. */ --	if (sp->fts_compar && nitems > 1) --		head = fts_sort(sp, head, nitems); --	return (head); -+mem3:	fts_lfree(root); -+	free(parent); -+mem2:	free(sp->fts_path); -+mem1:	free(sp); -+	return (NULL); - } -  --static u_short --fts_stat(sp, dp, p, follow) --	FTS *sp; --	register FTSENT *p; --	struct dirent *dp; --	int follow; -+FTSENT * -+fts_read(register FTS *sp) - { --	register FTSENT *t; --	register dev_t dev; --	register ino_t ino; --	struct stat *sbp, sb; -+	register FTSENT *p, *tmp; -+	register int instr; -+	register char *t; - 	int saved_errno; -  --	/* If user needs stat info, stat buffer already allocated. */ --	sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; -+	/* If finished or unrecoverable error, return NULL. */ -+	if (sp->fts_cur == NULL || ISSET(FTS_STOP)) -+		return (NULL); -  --#ifdef S_IFWHT --	/* --	 * Whited-out files don't really exist.  However, there's stat(2) file --	 * mask for them, so we set it so that programs (i.e., find) don't have --	 * to test FTS_W separately from other file types. --	 */ --	if (dp != NULL && dp->d_type == DT_WHT) { --		memset(sbp, 0, sizeof(struct stat)); --		sbp->st_mode = S_IFWHT; --		return (FTS_W); -+	/* Set current node pointer. */ -+	p = sp->fts_cur; -+ -+	/* Save and zero out user instructions. */ -+	instr = p->fts_instr; -+	p->fts_instr = FTS_NOINSTR; -+ -+	/* Any type of file may be re-visited; re-stat and re-turn. */ -+	if (instr == FTS_AGAIN) { -+		p->fts_info = fts_stat(sp, NULL, p, 0); -+		return (p); - 	} --#endif --	 -+ - 	/* --	 * If doing a logical walk, or application requested FTS_FOLLOW, do --	 * a stat(2).  If that fails, check for a non-existent symlink.  If --	 * fail, set the errno from the stat call. -+	 * Following a symlink -- SLNONE test allows application to see -+	 * SLNONE and recover.  If indirecting through a symlink, have -+	 * keep a pointer to current location.  If unable to get that -+	 * pointer, follow fails. - 	 */ --	if (ISSET(FTS_LOGICAL) || follow) { --		if (stat(p->fts_accpath, sbp)) { --			saved_errno = errno; --			if (!lstat(p->fts_accpath, sbp)) { --				errno = 0; --				return (FTS_SLNONE); --			}  --			p->fts_errno = saved_errno; --			goto err; -+	if (instr == FTS_FOLLOW && -+	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { -+		p->fts_info = fts_stat(sp, NULL, p, 1); -+		if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) -+			if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) { -+				p->fts_errno = errno; -+				p->fts_info = FTS_ERR; -+			} else -+				p->fts_flags |= FTS_SYMFOLLOW; -+		return (p); -+	} -+ -+	/* Directory in pre-order. */ -+	if (p->fts_info == FTS_D) { -+		/* If skipped or crossed mount point, do post-order visit. */ -+		if (instr == FTS_SKIP || -+		    ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) { -+			if (p->fts_flags & FTS_SYMFOLLOW) -+				(void)close(p->fts_symfd); -+			if (sp->fts_child) { -+				fts_lfree(sp->fts_child); -+				sp->fts_child = NULL; -+			} -+			p->fts_info = FTS_DP; -+			return (p); - 		} --	} else if (lstat(p->fts_accpath, sbp)) { --		p->fts_errno = errno; --err:		memset(sbp, 0, sizeof(struct stat)); --		return (FTS_NS); -+ -+		/* Rebuild if only read the names and now traversing. */ -+		if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) { -+			sp->fts_options &= ~FTS_NAMEONLY; -+			fts_lfree(sp->fts_child); -+			sp->fts_child = NULL; -+		} -+ -+		/* -+		 * Cd to the subdirectory. -+		 * -+		 * If have already read and now fail to chdir, whack the list -+		 * to make the names come out right, and set the parent errno -+		 * so the application will eventually get an error condition. -+		 * Set the FTS_DONTCHDIR flag so that when we logically change -+		 * directories back to the parent we don't do a chdir. -+		 * -+		 * If haven't read do so.  If the read fails, fts_build sets -+		 * FTS_STOP or the fts_info field of the node. -+		 */ -+		if (sp->fts_child) { -+			if (CHDIR(sp, p->fts_accpath)) { -+				p->fts_errno = errno; -+				p->fts_flags |= FTS_DONTCHDIR; -+				for (p = sp->fts_child; p; p = p->fts_link) -+					p->fts_accpath = -+					    p->fts_parent->fts_accpath; -+			} -+		} else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { -+			if (ISSET(FTS_STOP)) -+				return (NULL); -+			return (p); -+		} -+		p = sp->fts_child; -+		sp->fts_child = NULL; -+		goto name; - 	} -  --	if (S_ISDIR(sbp->st_mode)) { -+	/* Move to the next node on this level. */ -+next:	tmp = p; -+	if (p = p->fts_link) { -+		free(tmp); -+ - 		/* --		 * Set the device/inode.  Used to find cycles and check for --		 * crossing mount points.  Also remember the link count, used --		 * in fts_build to limit the number of stat calls.  It is --		 * understood that these fields are only referenced if fts_info --		 * is set to FTS_D. -+		 * If reached the top, return to the original directory, and -+		 * load the paths for the next root. - 		 */ --		dev = p->fts_dev = sbp->st_dev; --		ino = p->fts_ino = sbp->st_ino; --		p->fts_nlink = sbp->st_nlink; -+		if (p->fts_level == FTS_ROOTLEVEL) { -+			if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { -+				SET(FTS_STOP); -+				return (NULL); -+			} -+			fts_load(sp, p); -+			return (sp->fts_cur = p); -+		} -+ -+		/* -+		 * User may have called fts_set on the node.  If skipped, -+		 * ignore.  If followed, get a file descriptor so we can -+		 * get back if necessary. -+		 */ -+		if (p->fts_instr == FTS_SKIP) -+			goto next; -+		if (p->fts_instr == FTS_FOLLOW) { -+			p->fts_info = fts_stat(sp, NULL, p, 1); -+			if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) -+				if ((p->fts_symfd = -+				    open(".", O_RDONLY, 0)) < 0) { -+					p->fts_errno = errno; -+					p->fts_info = FTS_ERR; -+				} else -+					p->fts_flags |= FTS_SYMFOLLOW; -+			p->fts_instr = FTS_NOINSTR; -+		} -  --		if (ISDOT(p->fts_name)) --			return (FTS_DOT); -+name:		t = sp->fts_path + NAPPEND(p->fts_parent); -+		*t++ = '/'; -+		memmove(t, p->fts_name, p->fts_namelen + 1); -+		return (sp->fts_cur = p); -+	} -  -+	/* Move up to the parent node. */ -+	p = tmp->fts_parent; -+	free(tmp); -+ -+	if (p->fts_level == FTS_ROOTPARENTLEVEL) { - 		/* --		 * Cycle detection is done by brute force when the directory --		 * is first encountered.  If the tree gets deep enough or the --		 * number of symbolic links to directories is high enough, --		 * something faster might be worthwhile. -+		 * Done; free everything up and set errno to 0 so the user -+		 * can distinguish between error and EOF. - 		 */ --		for (t = p->fts_parent; --		    t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) --			if (ino == t->fts_ino && dev == t->fts_dev) { --				p->fts_cycle = t; --				return (FTS_DC); --			} --		return (FTS_D); -+		free(p); -+		errno = 0; -+		return (sp->fts_cur = NULL); - 	} --	if (S_ISLNK(sbp->st_mode)) --		return (FTS_SL); --	if (S_ISREG(sbp->st_mode)) --		return (FTS_F); --	return (FTS_DEFAULT); --} -  --static FTSENT * --fts_sort(sp, head, nitems) --	FTS *sp; --	FTSENT *head; --	register int nitems; --{ --	register FTSENT **ap, *p; -+	/* Nul terminate the pathname. */ -+	sp->fts_path[p->fts_pathlen] = '\0'; -  - 	/* --	 * Construct an array of pointers to the structures and call qsort(3). --	 * Reassemble the array in the order returned by qsort.  If unable to --	 * sort for memory reasons, return the directory entries in their --	 * current order.  Allocate enough space for the current needs plus --	 * 40 so don't realloc one entry at a time. -+	 * Return to the parent directory.  If at a root node or came through -+	 * a symlink, go back through the file descriptor.  Otherwise, cd up -+	 * one directory. - 	 */ --	if (nitems > sp->fts_nitems) { --		sp->fts_nitems = nitems + 40; --		if ((sp->fts_array = realloc(sp->fts_array, --		    (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) { --			sp->fts_nitems = 0; --			return (head); -+	if (p->fts_level == FTS_ROOTLEVEL) { -+		if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { -+			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); -+			errno = saved_errno; -+			SET(FTS_STOP); -+			return (NULL); -+		} -+		(void)close(p->fts_symfd); -+	} else if (!(p->fts_flags & FTS_DONTCHDIR)) { -+		if (CHDIR(sp, "..")) { -+			SET(FTS_STOP); -+			return (NULL); - 		} - 	} --	for (ap = sp->fts_array, p = head; p; p = p->fts_link) --		*ap++ = p; --	qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); --	for (head = *(ap = sp->fts_array); --nitems; ++ap) --		ap[0]->fts_link = ap[1]; --	ap[0]->fts_link = NULL; --	return (head); -+	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; -+	return (sp->fts_cur = p); - } -  --static FTSENT * --fts_alloc(sp, name, namelen) --	FTS *sp; --	char *name; --	register int namelen; -+/* -+ * Fts_set takes the stream as an argument although it's not used in this -+ * implementation; it would be necessary if anyone wanted to add global -+ * semantics to fts using fts_set.  An error return is allowed for similar -+ * reasons. -+ */ -+/* ARGSUSED */ -+int -+fts_set(FTS *sp, FTSENT *p, int instr) -+{ -+	if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && -+	    instr != FTS_NOINSTR && instr != FTS_SKIP) { -+		errno = EINVAL; -+		return (1); -+	} -+	p->fts_instr = instr; -+	return (0); -+} -+ -+FTSENT * -+fts_children(register FTS *sp, int instr) - { - 	register FTSENT *p; --	size_t len; -+	int fd; -+ -+	if (instr && instr != FTS_NAMEONLY) { -+		errno = EINVAL; -+		return (NULL); -+	} -+ -+	/* Set current node pointer. */ -+	p = sp->fts_cur; -  - 	/* --	 * The file name is a variable length array and no stat structure is --	 * necessary if the user has set the nostat bit.  Allocate the FTSENT --	 * structure, the file name and the stat structure in one chunk, but --	 * be careful that the stat structure is reasonably aligned.  Since the --	 * fts_name field is declared to be of size 1, the fts_name pointer is --	 * namelen + 2 before the first possible address of the stat structure. -+	 * Errno set to 0 so user can distinguish empty directory from -+	 * an error. - 	 */ --	len = sizeof(FTSENT) + namelen; --	if (!ISSET(FTS_NOSTAT)) --		len += sizeof(struct stat) + ALIGNBYTES; --	if ((p = malloc(len)) == NULL) -+	errno = 0; -+ -+	/* Fatal errors stop here. */ -+	if (ISSET(FTS_STOP)) - 		return (NULL); -  --	/* Copy the name plus the trailing NULL. */ --	memmove(p->fts_name, name, namelen + 1); -+	/* Return logical hierarchy of user's arguments. */ -+	if (p->fts_info == FTS_INIT) -+		return (p->fts_link); -  --	if (!ISSET(FTS_NOSTAT)) --		p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); --	p->fts_namelen = namelen; --	p->fts_path = sp->fts_path; --	p->fts_errno = 0; --	p->fts_flags = 0; --	p->fts_instr = FTS_NOINSTR; --	p->fts_number = 0; --	p->fts_pointer = NULL; --	return (p); -+	/* -+	 * If not a directory being visited in pre-order, stop here.  Could -+	 * allow FTS_DNR, assuming the user has fixed the problem, but the -+	 * same effect is available with FTS_AGAIN. -+	 */ -+	if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) -+		return (NULL); -+ -+	/* Free up any previous child list. */ -+	if (sp->fts_child) -+		fts_lfree(sp->fts_child); -+ -+	if (instr == FTS_NAMEONLY) { -+		sp->fts_options |= FTS_NAMEONLY; -+		instr = BNAMES; -+	} else -+		instr = BCHILD; -+ -+	/* -+	 * If using chdir on a relative path and called BEFORE fts_read does -+	 * its chdir to the root of a traversal, we can lose -- we need to -+	 * chdir into the subdirectory, and we don't know where the current -+	 * directory is, so we can't get back so that the upcoming chdir by -+	 * fts_read will work. -+	 */ -+	if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || -+	    ISSET(FTS_NOCHDIR)) -+		return (sp->fts_child = fts_build(sp, instr)); -+ -+	if ((fd = open(".", O_RDONLY, 0)) < 0) -+		return (NULL); -+	sp->fts_child = fts_build(sp, instr); -+	if (fchdir(fd)) -+		return (NULL); -+	(void)close(fd); -+	return (sp->fts_child); - } -  --static void --fts_lfree(head) --	register FTSENT *head; -+int -+fts_close(FTS *sp) - { --	register FTSENT *p; -+	register FTSENT *freep, *p; -+	int saved_errno; -  --	/* Free a linked list of structures. */ --	while (p = head) { --		head = head->fts_link; -+	/* -+	 * This still works if we haven't read anything -- the dummy structure -+	 * points to the root list, so we step through to the end of the root -+	 * list which has a valid parent pointer. -+	 */ -+	if (sp->fts_cur) { -+		for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { -+			freep = p; -+			p = p->fts_link ? p->fts_link : p->fts_parent; -+			free(freep); -+		} - 		free(p); - 	} --} -  --/* -- * Allow essentially unlimited paths; find, rm, ls should all work on any tree. -- * Most systems will allow creation of paths much longer than MAXPATHLEN, even -- * though the kernel won't resolve them.  Add the size (not just what's needed) -- * plus 256 bytes so don't realloc the path 2 bytes at a time.  -- */ --static int --fts_palloc(sp, more) --	FTS *sp; --	size_t more; --{ --	sp->fts_pathlen += more + 256; --	sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen); --	return (sp->fts_path == NULL); --} -+	/* Free up child linked list, sort array, path buffer. */ -+	if (sp->fts_child) -+		fts_lfree(sp->fts_child); -+	if (sp->fts_array) -+		free(sp->fts_array); -+	free(sp->fts_path); -  --/* -- * When the path is realloc'd, have to fix all of the pointers in structures -- * already returned. -- */ --static void --fts_padjust(sp, addr) --	FTS *sp; --	void *addr; --{ --	FTSENT *p; -+	/* Return to original directory, save errno if necessary. */ -+	if (!ISSET(FTS_NOCHDIR)) { -+		saved_errno = fchdir(sp->fts_rfd) ? errno : 0; -+		(void)close(sp->fts_rfd); -+	} -  --#define	ADJUST(p) {							\ --	(p)->fts_accpath =						\ --	    (char *)addr + ((p)->fts_accpath - (p)->fts_path);		\ --	(p)->fts_path = addr;						\ --} --	/* Adjust the current set of children. */ --	for (p = sp->fts_child; p; p = p->fts_link) --		ADJUST(p); -+	/* Free up the stream pointer. */ -+	free(sp); -  --	/* Adjust the rest of the tree. */ --	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { --		ADJUST(p); --		p = p->fts_link ? p->fts_link : p->fts_parent; -+	/* Set errno and return. */ -+	if (!ISSET(FTS_NOCHDIR) && saved_errno) { -+		errno = saved_errno; -+		return (-1); - 	} -+	return (0); - } -  --static size_t --fts_maxarglen(argv) --	char * const *argv; --{ --	size_t len, max; -- --	for (max = 0; *argv; ++argv) --		if ((len = strlen(*argv)) > max) --			max = len; --	return (max); --} diff --git a/meta/recipes-core/fts/fts/remove_cdefs.patch b/meta/recipes-core/fts/fts/remove_cdefs.patch deleted file mode 100644 index c152704d44..0000000000 --- a/meta/recipes-core/fts/fts/remove_cdefs.patch +++ /dev/null @@ -1,69 +0,0 @@ -Replace use of macros from sys/cdefs.h since cdefs.h is missing on musl - -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Upstream-Status: Inappropriate - -Index: fts/fts.h -=================================================================== ---- fts.orig/fts.h -+++ fts/fts.h -@@ -126,15 +126,21 @@ typedef struct _ftsent { - 	char fts_name[1];		/* file name */ - } FTSENT; -  --#include <sys/cdefs.h> -+#ifdef __cplusplus -+extern "C" { -+#endif -  --__BEGIN_DECLS --FTSENT	*fts_children __P((FTS *, int)); --int	 fts_close __P((FTS *)); --FTS	*fts_open __P((char * const *, int, --	    int (*)(const FTSENT **, const FTSENT **))); --FTSENT	*fts_read __P((FTS *)); --int	 fts_set __P((FTS *, FTSENT *, int)); --__END_DECLS -+#ifndef __P -+#define __P -+#endif -+FTSENT	*fts_children (FTS *p, int opts); -+int	 fts_close (FTS *p); -+FTS	*fts_open (char * const * path, int opts, -+	    int (*compfn)(const FTSENT **, const FTSENT **)); -+FTSENT	*fts_read (FTS *p); -+int	 fts_set (FTS *p, FTSENT *f, int opts); -  -+#ifdef __cplusplus -+} -+#endif - #endif /* !_FTS_H_ */ -Index: fts/fts.c -=================================================================== ---- fts.orig/fts.c -+++ fts/fts.c -@@ -50,15 +50,15 @@ static char sccsid[] = "@(#)fts.c	8.6 (B - #include <string.h> - #include <unistd.h> -  --static FTSENT	*fts_alloc __P((FTS *, char *, int)); --static FTSENT	*fts_build __P((FTS *, int)); --static void	 fts_lfree __P((FTSENT *)); --static void	 fts_load __P((FTS *, FTSENT *)); --static size_t	 fts_maxarglen __P((char * const *)); --static void	 fts_padjust __P((FTS *, void *)); --static int	 fts_palloc __P((FTS *, size_t)); --static FTSENT	*fts_sort __P((FTS *, FTSENT *, int)); --static u_short	 fts_stat __P((FTS *, struct dirent *, FTSENT *, int)); -+static FTSENT	*fts_alloc __P(FTS *, char *, int); -+static FTSENT	*fts_build __P(FTS *, int); -+static void	 fts_lfree __P(FTSENT *); -+static void	 fts_load __P(FTS *, FTSENT *); -+static size_t	 fts_maxarglen __P(char * const *); -+static void	 fts_padjust __P(FTS *, void *); -+static int	 fts_palloc __P(FTS *, size_t); -+static FTSENT	*fts_sort __P(FTS *, FTSENT *, int); -+static u_short	 fts_stat __P(FTS *, struct dirent *, FTSENT *, int); -  - #define	ISDOT(a)	(a[0] == '.' && (!a[1] || a[1] == '.' && !a[2])) -  diff --git a/meta/recipes-core/fts/fts/stdint.patch b/meta/recipes-core/fts/fts/stdint.patch deleted file mode 100644 index 89e6097fcb..0000000000 --- a/meta/recipes-core/fts/fts/stdint.patch +++ /dev/null @@ -1,15 +0,0 @@ -Include stdint.h for u_* typedefs - -Signed-off-by: Khem Raj <raj.khem@gmail.com> -Upstream-Status: Inappropriate - ---- ./fts.c.orig -+++ ./fts.c -@@ -46,6 +46,7 @@ - #include <errno.h> - #include <fcntl.h> - #include <fts.h> -+#include <stdint.h> - #include <stdlib.h> - #include <string.h> - #include <unistd.h> | 
