Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2001 15:34:16 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        Bruce Evans <bde@zeta.org.au>, Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Cc:        current@FreeBSD.org
Subject:   fts_open() (was: Re: Patch to restore WARNS feature)
Message-ID:  <20010613153416.B21292@sunbay.com>
In-Reply-To: <Pine.BSF.4.21.0106121429190.57306-100000@besplex.bde.org>; from bde@zeta.org.au on Tue, Jun 12, 2001 at 02:35:39PM %2B1000
References:  <20010611212628.A37954@sunbay.com> <20010612155318.B79617@sunbay.com> <200106121838.OAA91929@khavrinen.lcs.mit.edu> <20010611213543.A50405@sunbay.com> <Pine.BSF.4.21.0106121429190.57306-100000@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Should I commit the attached patch then?

On Tue, Jun 12, 2001 at 02:35:39PM +1000, Bruce Evans wrote:
> > For those interested, here's the missing patch.
> 
> Index: lib/libc/gen/fts.c
> ===================================================================
> RCS file: /home/ncvs/src/lib/libc/gen/fts.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 fts.c
> --- lib/libc/gen/fts.c	2001/06/01 21:53:50	1.18
> +++ lib/libc/gen/fts.c	2001/06/11 18:20:17
> @@ -936,7 +936,8 @@ fts_sort(sp, head, nitems)
>  	}
>  	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);
> +	qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *),
> +	    (int (*) __P((const void *, const void *)))sp->fts_compar);
>  	for (head = *(ap = sp->fts_array); --nitems; ++ap)
>  		ap[0]->fts_link = ap[1];
>  	ap[0]->fts_link = NULL;
> 
> This just hides the bug that fts's comparison function is not suitable
> for use by qsort().
> 
> Bruce

On Tue, Jun 12, 2001 at 02:38:13PM -0400, Garrett Wollman wrote:
> <<On Tue, 12 Jun 2001 15:53:18 +0300, Ruslan Ermilov <ru@FreeBSD.org> said:
> 
> > +	qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *),
> > +	    (int (*) __P((const void *, const void *)))sp->fts_compar);
> 
> This is wrong.  The declaration of the comparison function should be
> fixed, rather than papering over the mistake here.
> 
> (This is arguably a deficiency in the C standard.  qsort() should take
> an additional state parameter for the comparison function, but
> doesn't.)
> 


-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=p

Index: include/fts.h
===================================================================
RCS file: /home/ncvs/src/include/fts.h,v
retrieving revision 1.3
diff -u -p -r1.3 fts.h
--- include/fts.h	1997/05/07 19:59:58	1.3
+++ include/fts.h	2001/06/13 12:17:31
@@ -45,7 +45,8 @@ typedef struct {
 	int fts_rfd;			/* fd for root */
 	int fts_pathlen;		/* sizeof(path) */
 	int fts_nitems;			/* elements in the sort array */
-	int (*fts_compar)();		/* compare function */
+	int (*fts_compar)		/* compare function */
+	    __P((const void *, const void *));
 
 #define	FTS_COMFOLLOW	0x001		/* follow command line symlinks */
 #define	FTS_LOGICAL	0x002		/* logical walk */
@@ -120,7 +121,7 @@ __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 **)));
+	    int (*)(const void *, const void *)));
 FTSENT	*fts_read __P((FTS *));
 int	 fts_set __P((FTS *, FTSENT *, int));
 __END_DECLS
Index: lib/libc/gen/fts.3
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/fts.3,v
retrieving revision 1.12
diff -u -p -r1.12 fts.3
--- lib/libc/gen/fts.3	2001/02/01 16:29:34	1.12
+++ lib/libc/gen/fts.3	2001/06/13 12:17:32
@@ -45,7 +45,7 @@
 .Fd #include <sys/stat.h>
 .Fd #include <fts.h>
 .Ft FTS *
-.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const FTSENT **, const FTSENT **)"
+.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const void *, const void *)"
 .Ft FTSENT *
 .Fn fts_read "FTS *ftsp"
 .Ft FTSENT *
@@ -462,9 +462,9 @@ The argument
 specifies a user-defined function which may be used to order the traversal
 of the hierarchy.
 It
-takes two pointers to pointers to
-.Fa FTSENT
-structures as arguments and
+takes two pointers as arguments (which need to be cast to
+.Vt "FTSENT **"
+inside the function's body) and
 should return a negative value, zero, or a positive value to indicate
 if the file referenced by its first argument comes before, in any order
 with respect to, or after, the file referenced by its second argument.
Index: lib/libc/gen/fts.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/fts.c,v
retrieving revision 1.18
diff -u -p -r1.18 fts.c
--- lib/libc/gen/fts.c	2001/06/01 21:53:50	1.18
+++ lib/libc/gen/fts.c	2001/06/13 12:17:35
@@ -85,7 +85,7 @@ FTS *
 fts_open(argv, options, compar)
 	char * const *argv;
 	register int options;
-	int (*compar) __P((const FTSENT **, const FTSENT **));
+	int (*compar) __P((const void *, const void *));
 {
 	register FTS *sp;
 	register FTSENT *p, *root;
Index: bin/cp/cp.c
===================================================================
RCS file: /home/ncvs/src/bin/cp/cp.c,v
retrieving revision 1.26
diff -u -p -r1.26 cp.c
--- bin/cp/cp.c	2001/06/11 13:57:54	1.26
+++ bin/cp/cp.c	2001/06/13 12:17:35
@@ -88,7 +88,7 @@ int Rflag, iflag, pflag, rflag, fflag, v
 enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
 
 int copy __P((char *[], enum op, int));
-int mastercmp __P((const FTSENT **, const FTSENT **));
+int mastercmp __P((const void *, const void *));
 
 int
 main(argc, argv)
@@ -428,14 +428,14 @@ copy(argv, type, fts_options)
  */
 int
 mastercmp(a, b)
-	const FTSENT **a, **b;
+	const void *a, *b;
 {
 	int a_info, b_info;
 
-	a_info = (*a)->fts_info;
+	a_info = (*(FTSENT **)a)->fts_info;
 	if (a_info == FTS_ERR || a_info == FTS_NS || a_info == FTS_DNR)
 		return (0);
-	b_info = (*b)->fts_info;
+	b_info = (*(FTSENT **)b)->fts_info;
 	if (b_info == FTS_ERR || b_info == FTS_NS || b_info == FTS_DNR)
 		return (0);
 	if (a_info == FTS_D)
Index: bin/ls/ls.c
===================================================================
RCS file: /home/ncvs/src/bin/ls/ls.c,v
retrieving revision 1.45
diff -u -p -r1.45 ls.c
--- bin/ls/ls.c	2000/08/13 12:17:03	1.45
+++ bin/ls/ls.c	2001/06/13 12:17:35
@@ -80,7 +80,7 @@ static const char rcsid[] =
 
 static void	 display __P((FTSENT *, FTSENT *));
 static u_quad_t	 makenines __P((u_long));
-static int	 mastercmp __P((const FTSENT **, const FTSENT **));
+static int	 mastercmp __P((const void *, const void *));
 static void	 traverse __P((int, char **, int));
 
 static void (*printfcn) __P((DISPLAY *));
@@ -679,28 +679,28 @@ display(p, list)
  */
 static int
 mastercmp(a, b)
-	const FTSENT **a, **b;
+	const void *a, *b;
 {
 	int a_info, b_info;
 
-	a_info = (*a)->fts_info;
+	a_info = (*(FTSENT **)a)->fts_info;
 	if (a_info == FTS_ERR)
 		return (0);
-	b_info = (*b)->fts_info;
+	b_info = (*(FTSENT **)b)->fts_info;
 	if (b_info == FTS_ERR)
 		return (0);
 
 	if (a_info == FTS_NS || b_info == FTS_NS)
-		return (namecmp(*a, *b));
+		return (namecmp(*(FTSENT **)a, *(FTSENT **)b));
 
 	if (a_info != b_info &&
-	    (*a)->fts_level == FTS_ROOTLEVEL && !f_listdir) {
+	    (*(FTSENT **)a)->fts_level == FTS_ROOTLEVEL && !f_listdir) {
 		if (a_info == FTS_D)
 			return (1);
 		if (b_info == FTS_D)
 			return (-1);
 	}
-	return (sortfcn(*a, *b));
+	return (sortfcn(*(FTSENT **)a, *(FTSENT **)b));
 }
 
 /*
Index: bin/rm/rm.c
===================================================================
RCS file: /home/ncvs/src/bin/rm/rm.c,v
retrieving revision 1.32
diff -u -p -r1.32 rm.c
--- bin/rm/rm.c	2000/12/20 08:31:26	1.32
+++ bin/rm/rm.c	2001/06/13 12:17:36
@@ -183,7 +183,7 @@ rm_tree(argv)
 		flags |= FTS_NOSTAT;
 	if (Wflag)
 		flags |= FTS_WHITEOUT;
-	if (!(fts = fts_open(argv, flags, (int (*)())NULL)))
+	if (!(fts = fts_open(argv, flags, NULL)))
 		err(1, NULL);
 	while ((p = fts_read(fts)) != NULL) {
 		switch (p->fts_info) {
Index: usr.bin/find/find.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/find.c,v
retrieving revision 1.10
diff -u -p -r1.10 find.c
--- usr.bin/find/find.c	2001/05/03 18:05:34	1.10
+++ usr.bin/find/find.c	2001/06/13 12:17:36
@@ -56,7 +56,7 @@ static const char rcsid[] =
 
 #include "find.h"
 
-static int	find_compare __P((const FTSENT **s1, const FTSENT **s2));
+static int	find_compare __P((const void *s1, const void *s2));
 
 /*
  * find_compare --
@@ -66,10 +66,10 @@ static int	find_compare __P((const FTSEN
  */
 static int
 find_compare(s1, s2)
-	const FTSENT **s1, **s2;
+	const void *s1, *s2;
 {
 
-	return (strcoll((*s1)->fts_name, (*s2)->fts_name));
+	return (strcoll((*(FTSENT **)s1)->fts_name, (*(FTSENT **)s2)->fts_name));
 }
 
 /*
Index: usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c,v
retrieving revision 1.9
diff -u -p -r1.9 ctm_dequeue.c
--- usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c	1999/08/28 01:16:01	1.9
+++ usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c	2001/06/13 12:17:36
@@ -53,7 +53,7 @@
 
 #define DEFAULT_NUM	1	/* Default number of pieces mailed per run. */
 
-int fts_sort(const FTSENT **, const FTSENT **);
+int fts_sort(const void *, const void *);
 int run_sendmail(int ifd);
 
 int
@@ -156,14 +156,14 @@ main(int argc, char **argv)
 }
 
 int
-fts_sort(const FTSENT ** a, const FTSENT ** b)
+fts_sort(const void *a, const void *b)
 {
-    if ((*a)->fts_info != FTS_F)
+    if ((*(FTSENT **)a)->fts_info != FTS_F)
 	return(0);
-    if ((*a)->fts_info != FTS_F)
+    if ((*(FTSENT **)a)->fts_info != FTS_F)
 	return(0);
 
-    return (strcmp((*a)->fts_name, (*b)->fts_name));
+    return (strcmp((*(FTSENT **)a)->fts_name, (*(FTSENT **)b)->fts_name));
 }
 
 /*
Index: usr.sbin/mtree/create.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/mtree/create.c,v
retrieving revision 1.21
diff -u -p -r1.21 create.c
--- usr.sbin/mtree/create.c	2000/10/03 13:13:47	1.21
+++ usr.sbin/mtree/create.c	2001/06/13 12:17:36
@@ -79,7 +79,7 @@ static uid_t uid;
 static mode_t mode;
 static u_long flags = 0xffffffff;
 
-static int	dsort __P((const FTSENT **, const FTSENT **));
+static int	dsort __P((const void *, const void *));
 static void	output __P((int, int *, const char *, ...));
 static int	statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *,
 			   u_long *));
@@ -396,14 +396,14 @@ statd(t, parent, puid, pgid, pmode, pfla
 
 static int
 dsort(a, b)
-	const FTSENT **a, **b;
+	const void *a, *b;
 {
-	if (S_ISDIR((*a)->fts_statp->st_mode)) {
-		if (!S_ISDIR((*b)->fts_statp->st_mode))
+	if (S_ISDIR((*(FTSENT **)a)->fts_statp->st_mode)) {
+		if (!S_ISDIR((*(FTSENT **)b)->fts_statp->st_mode))
 			return (1);
-	} else if (S_ISDIR((*b)->fts_statp->st_mode))
+	} else if (S_ISDIR((*(FTSENT **)b)->fts_statp->st_mode))
 		return (-1);
-	return (strcmp((*a)->fts_name, (*b)->fts_name));
+	return (strcmp((*(FTSENT **)a)->fts_name, (*(FTSENT **)b)->fts_name));
 }
 
 #if __STDC__
Index: usr.sbin/pkg_install/lib/match.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/pkg_install/lib/match.c,v
retrieving revision 1.4
diff -u -p -r1.4 match.c
--- usr.sbin/pkg_install/lib/match.c	2001/03/23 18:45:24	1.4
+++ usr.sbin/pkg_install/lib/match.c	2001/06/13 12:17:36
@@ -41,7 +41,7 @@ struct store {
 
 static int rex_match(char *, char *);
 static int storeappend(struct store *, const char *);
-static int fname_cmp(const FTSENT **, const FTSENT **);
+static int fname_cmp(const void *, const void *);
 
 /*
  * Function to query names of installed packages.
@@ -230,7 +230,7 @@ storeappend(struct store *store, const c
 }
 
 static int
-fname_cmp(const FTSENT **a, const FTSENT **b)
+fname_cmp(const void *a, const void *b)
 {
-    return strcmp((*a)->fts_name, (*b)->fts_name);
+    return strcmp((*(FTSENT **)a)->fts_name, (*(FTSENT **)b)->fts_name);
 }

--nFreZHaLTZJo0R7j--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010613153416.B21292>