/bin/ls sorting bug?

David Malone dwmalone at maths.tcd.ie
Sun Jun 20 08:59:26 GMT 2004


On Sat, Jun 19, 2004 at 11:52:29PM +0100, Scott Mitchell wrote:
> On Sat, Jun 19, 2004 at 10:06:01PM +0200, Dimitry Andric wrote:
> > Looking through ls source shows that the sorting is done by passing a
> > comparison function to fts_open(3).  In the case of sorting by
> > modification time, the *only* comparison made is of the mtime fields:
> 
> You did see the patch attached to my original post, right?  It modifies all
> of these comparison functions to sort the two items by name (or reverse
> name) in the case that their timestamps are equal.

Hi Scott,

Could you produce a version of your patch that uses the nanoseconds
field too? I produced the one below, but I think the style in your
patch was nicer. Also, I wonder if the revblahcmp functions should
just call blahcmp with their arguments reversed?

	David.


Index: cmp.c
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/bin/ls/cmp.c,v
retrieving revision 1.13
diff -u -r1.13 cmp.c
--- cmp.c	6 Apr 2004 20:06:47 -0000	1.13
+++ cmp.c	19 Jun 2004 21:23:01 -0000
@@ -63,35 +63,107 @@
 int
 modcmp(const FTSENT *a, const FTSENT *b)
 {
-	return (b->fts_statp->st_mtime - a->fts_statp->st_mtime);
+	if (b->fts_statp->st_mtimespec.tv_sec >
+	    a->fts_statp->st_mtimespec.tv_sec)
+		return 1;
+	if (b->fts_statp->st_mtimespec.tv_sec <
+	    a->fts_statp->st_mtimespec.tv_sec)
+		return -1;
+	if (b->fts_statp->st_mtimespec.tv_nsec >
+	    a->fts_statp->st_mtimespec.tv_nsec)
+		return 1;
+	if (b->fts_statp->st_mtimespec.tv_nsec <
+	    a->fts_statp->st_mtimespec.tv_nsec)
+		return -1;
+	return (strcoll(a->fts_name, b->fts_name));
 }
 
 int
 revmodcmp(const FTSENT *a, const FTSENT *b)
 {
-	return (a->fts_statp->st_mtime - b->fts_statp->st_mtime);
+	if (a->fts_statp->st_mtimespec.tv_sec >
+	    b->fts_statp->st_mtimespec.tv_sec)
+		return 1;
+	if (a->fts_statp->st_mtimespec.tv_sec <
+	    b->fts_statp->st_mtimespec.tv_sec)
+		return -1;
+	if (a->fts_statp->st_mtimespec.tv_nsec >
+	    b->fts_statp->st_mtimespec.tv_nsec)
+		return 1;
+	if (a->fts_statp->st_mtimespec.tv_nsec <
+	    b->fts_statp->st_mtimespec.tv_nsec)
+		return -1;
+	return (strcoll(b->fts_name, a->fts_name));
 }
 
 int
 acccmp(const FTSENT *a, const FTSENT *b)
 {
-	return (b->fts_statp->st_atime - a->fts_statp->st_atime);
+	if (b->fts_statp->st_atimespec.tv_sec >
+	    a->fts_statp->st_atimespec.tv_sec)
+		return 1;
+	if (b->fts_statp->st_atimespec.tv_sec <
+	    a->fts_statp->st_atimespec.tv_sec)
+		return -1;
+	if (b->fts_statp->st_atimespec.tv_nsec >
+	    a->fts_statp->st_atimespec.tv_nsec)
+		return 1;
+	if (b->fts_statp->st_atimespec.tv_nsec <
+	    a->fts_statp->st_atimespec.tv_nsec)
+		return -1;
+	return (strcoll(a->fts_name, b->fts_name));
 }
 
 int
 revacccmp(const FTSENT *a, const FTSENT *b)
 {
-	return (a->fts_statp->st_atime - b->fts_statp->st_atime);
+	if (a->fts_statp->st_atimespec.tv_sec >
+	    b->fts_statp->st_atimespec.tv_sec)
+		return 1;
+	if (a->fts_statp->st_atimespec.tv_sec <
+	    b->fts_statp->st_atimespec.tv_sec)
+		return -1;
+	if (a->fts_statp->st_atimespec.tv_nsec >
+	    b->fts_statp->st_atimespec.tv_nsec)
+		return 1;
+	if (a->fts_statp->st_atimespec.tv_nsec <
+	    b->fts_statp->st_atimespec.tv_nsec)
+		return -1;
+	return (strcoll(b->fts_name, a->fts_name));
 }
 
 int
 statcmp(const FTSENT *a, const FTSENT *b)
 {
-	return (b->fts_statp->st_ctime - a->fts_statp->st_ctime);
+	if (b->fts_statp->st_ctimespec.tv_sec >
+	    a->fts_statp->st_ctimespec.tv_sec)
+		return 1;
+	if (b->fts_statp->st_ctimespec.tv_sec <
+	    a->fts_statp->st_ctimespec.tv_sec)
+		return -1;
+	if (b->fts_statp->st_ctimespec.tv_nsec >
+	    a->fts_statp->st_ctimespec.tv_nsec)
+		return 1;
+	if (b->fts_statp->st_ctimespec.tv_nsec <
+	    a->fts_statp->st_ctimespec.tv_nsec)
+		return -1;
+	return (strcoll(a->fts_name, b->fts_name));
 }
 
 int
 revstatcmp(const FTSENT *a, const FTSENT *b)
 {
-	return (a->fts_statp->st_ctime - b->fts_statp->st_ctime);
+	if (a->fts_statp->st_ctimespec.tv_sec >
+	    b->fts_statp->st_ctimespec.tv_sec)
+		return 1;
+	if (a->fts_statp->st_ctimespec.tv_sec <
+	    b->fts_statp->st_ctimespec.tv_sec)
+		return -1;
+	if (a->fts_statp->st_ctimespec.tv_nsec >
+	    b->fts_statp->st_ctimespec.tv_nsec)
+		return 1;
+	if (a->fts_statp->st_ctimespec.tv_nsec <
+	    b->fts_statp->st_ctimespec.tv_nsec)
+		return -1;
+	return (strcoll(b->fts_name, a->fts_name));
 }


More information about the freebsd-hackers mailing list