git: 79679a18eacb - main - fts: Simplify fts_alloc() and use calloc().

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Fri, 01 Nov 2024 15:53:17 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=79679a18eacbd0f34d24d749ee379e3089045c00

commit 79679a18eacbd0f34d24d749ee379e3089045c00
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-11-01 15:51:56 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-11-01 15:53:11 +0000

    fts: Simplify fts_alloc() and use calloc().
    
    Sponsored by:   Klara, Inc.
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D47382
---
 lib/libc/gen/fts.c | 41 +++++++++++++++--------------------------
 1 file changed, 15 insertions(+), 26 deletions(-)

diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
index 976edacc361e..770a7b2cc322 100644
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -40,6 +40,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <fts.h>
+#include <stdalign.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -1026,44 +1027,32 @@ fts_alloc(FTS *sp, char *name, size_t namelen)
 	FTSENT *p;
 	size_t len;
 
-	struct ftsent_withstat {
-		FTSENT	ent;
-		struct	stat statbuf;
-	};
-
 	/*
 	 * 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.
 	 */
-	if (ISSET(FTS_NOSTAT))
-		len = sizeof(FTSENT) + namelen + 1;
-	else
-		len = sizeof(struct ftsent_withstat) + namelen + 1;
-
-	if ((p = malloc(len)) == NULL)
-		return (NULL);
-
-	if (ISSET(FTS_NOSTAT)) {
-		p->fts_name = (char *)(p + 1);
-		p->fts_statp = NULL;
+	len = sizeof(FTSENT) + namelen + 1;
+	if (!ISSET(FTS_NOSTAT)) {
+		len = roundup(len, alignof(struct stat));
+		p = calloc(1, len + sizeof(struct stat));
 	} else {
-		p->fts_name = (char *)((struct ftsent_withstat *)p + 1);
-		p->fts_statp = &((struct ftsent_withstat *)p)->statbuf;
+		p = calloc(1, len);
 	}
+	if (p == NULL)
+		return (NULL);
 
-	/* Copy the name and guarantee NUL termination. */
-	memcpy(p->fts_name, name, namelen);
-	p->fts_name[namelen] = '\0';
-	p->fts_namelen = namelen;
+	p->fts_symfd = -1;
 	p->fts_path = sp->fts_path;
-	p->fts_errno = 0;
-	p->fts_flags = 0;
+	p->fts_name = (char *)(p + 1);
+	p->fts_namelen = namelen;
 	p->fts_instr = FTS_NOINSTR;
-	p->fts_number = 0;
-	p->fts_pointer = NULL;
+	if (!ISSET(FTS_NOSTAT))
+		p->fts_statp = (struct stat *)((char *)p + len);
 	p->fts_fts = sp;
+	memcpy(p->fts_name, name, namelen);
+
 	return (p);
 }