bug#33025: Add examples of why one would want to "sort" something "randomly"

2018-10-12 Thread 積丹尼 Dan Jacobson
On (info "(coreutils) sort invocation")

‘-R’
‘--random-sort’
‘--sort=random’
 Sort by hashing the input keys and then sorting the hash values.
 Choose the hash function at random, ensuring that it is free of
 collisions so that differing keys have differing hash values.  This
 is like a random permutation of the inputs (*note shuf
 invocation::), except that keys with the same value sort
 together...

OK, but you need to mention some examples of why someone would want to
"sort" something "randomly".

OK, I have one:

You have a list of URLs.

You know there are probably duplicates in there, that you want to get
rid of.

But you also don't want to make it look like you have "machine sorted
them." You want them to still look "hand assembled."

So you use sort --random-sort --unique on them!





bug#6816: df bug on 64-bit Solaris (need to use getextmntent)

2018-10-12 Thread Bruno Haible
David Wood wrote:
> >> At this point, me->me_dev contains a wrongly packed (32-bit) device 
> >> number, which forces the find_mount_point() code path (causing other 
> >> unpleasantries).  The following patch against coreutils v8.5 fixes the 
> >> problem:

This problem description was to the point, but I needed a bit of time to
understand the issue entirely.

On Solaris, gnulib's mountlist module proceeds by reading the /etc/mnttab
file.

https://docs.oracle.com/cd/E86824_01/html/E54775/mnttab-4.html says:
  "The mnttab file system provides the previously undocumented dev=xxx option
   in the option string for each mounted file system. This is provided for
   legacy applications that might have been using the dev=information option.

   Using dev=option in applications is strongly discouraged. The device number
   string represents a 32-bit quantity and might not contain correct
   information in 64-bit environments.

   Applications requiring device number information for mounted file systems
   should use the getextmntent(3C) interface, which functions properly in
   either 32- or 64-bit environments."

The 'stat' program displays a dev_t. For example, for '/':
A 32-bit 'stat': 4750002 = (0x11d << 18) + (0x10002 << 0)
A 64-bit 'stat': 11d00010002 = (0x11d << 32) + (0x10002 << 0)

So, device numbers in a 32-bit program and in a 64-bit program are
different!

Additionally, reading /etc/mnttab produces the same(!) result when
done by a 64-bit program as by a 32-bit program. The approach that
converts the dev=... strings found in /etc/mnttab therefore produces
dev_t values according to 32-bit programs, even in a 64-bit program.

Now comes GNU 'df' which, as David noted, has logic to compare the
two dev_t values:
./src/df.c:1371:  me->me_dev = disk_stats.st_dev;
./src/df.c:1388:if (statp->st_dev == me->me_dev
./src/df.c:1394:|| disk_stats.st_dev != me->me_dev)

So, really, we need to avoid the wrongly encoded dev_t values, and
this means to follow the advice from the mnttab.4 man page.


2018-10-12  Bruno Haible  

mountlist: Improve support for Solaris in 64-bit mode.
Reported by David Wood  in
.
* m4/ls-mntd-fs.m4 (gl_LIST_MOUNTED_FILE_SYSTEMS): On Solaris 8 or
newer, define MOUNTED_GETEXTMNTENT instead of MOUNTED_GETMNTENT2.
* lib/mountlist.c: Add code for MOUNTED_GETEXTMNTENT case.

diff --git a/lib/mountlist.c b/lib/mountlist.c
index 970c611..845c348 100644
--- a/lib/mountlist.c
+++ b/lib/mountlist.c
@@ -111,7 +111,11 @@
 # include 
 #endif
 
-#ifdef MOUNTED_GETMNTENT2   /* Solaris, also (obsolete) SVR4 */
+#ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */
+# include 
+#endif
+
+#ifdef MOUNTED_GETMNTENT2   /* Solaris < 8, also (obsolete) SVR4 */
 # include 
 #endif
 
@@ -918,10 +922,55 @@ read_file_system_list (bool need_fs_type)
   }
 #endif /* MOUNTED_GETMNTTBL */
 
-#ifdef MOUNTED_GETMNTENT2   /* Solaris, also (obsolete) SVR4 */
+#ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */
+  {
+struct extmnttab mnt;
+const char *table = MNTTAB;
+FILE *fp;
+int ret;
+
+/* No locking is needed, because the contents of /etc/mnttab is generated
+   by the kernel.  */
+
+errno = 0;
+fp = fopen (table, "r");
+if (fp == NULL)
+  ret = errno;
+else
+  {
+while ((ret = getextmntent (fp, , 1)) == 0)
+  {
+me = xmalloc (sizeof *me);
+me->me_devname = xstrdup (mnt.mnt_special);
+me->me_mountdir = xstrdup (mnt.mnt_mountp);
+me->me_mntroot = NULL;
+me->me_type = xstrdup (mnt.mnt_fstype);
+me->me_type_malloced = 1;
+me->me_dummy = MNT_IGNORE () != 0;
+me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
+me->me_dev = makedev (mnt.mnt_major, mnt.mnt_minor);
+
+/* Add to the linked list. */
+*mtail = me;
+mtail = >me_next;
+  }
+
+ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
+/* Here ret = -1 means success, ret >= 0 means failure.  */
+  }
+
+if (0 <= ret)
+  {
+errno = ret;
+goto free_then_fail;
+  }
+  }
+#endif /* MOUNTED_GETMNTTBL */
+
+#ifdef MOUNTED_GETMNTENT2   /* Solaris < 8, also (obsolete) SVR4 */
   {
 struct mnttab mnt;
-char *table = MNTTAB;
+const char *table = MNTTAB;
 FILE *fp;
 int ret;
 int lockfd = -1;
@@ -979,6 +1028,7 @@ read_file_system_list (bool need_fs_type)
   }
 
 ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
+/* Here ret = -1 means success, ret >= 0 means failure.  */
   }
 
 if (0 <= lockfd && close (lockfd) != 0)
diff --git a/m4/ls-mntd-fs.m4 b/m4/ls-mntd-fs.m4
index ff688f5..643d0ce 100644
--- a/m4/ls-mntd-fs.m4
+++ b/m4/ls-mntd-fs.m4
@@ -158,7 +158,23 @@ yes
 fi
 
 if test -z "$ac_list_mounted_fs";