6ee4d0
diff --git a/src/df.c b/src/df.c
6ee4d0
index e28a656..fe222d9 100644
6ee4d0
--- a/src/df.c
6ee4d0
+++ b/src/df.c
6ee4d0
@@ -45,12 +45,12 @@
f180de
 
f180de
 /* Filled with device numbers of examined file systems to avoid
f180de
    duplicities in output.  */
f180de
-struct devlist
f180de
+static struct devlist
f180de
 {
f180de
   dev_t dev_num;
f180de
   struct mount_entry *me;
f180de
   struct devlist *next;
f180de
-};
f180de
+} *device_list;
f180de
 
f180de
 /* If true, show even file systems with zero size or
f180de
    uninteresting types.  */
6ee4d0
@@ -609,13 +609,10 @@ excluded_fstype (const char *fstype)
f180de
    me_mountdir wins.  */
f180de
 
f180de
 static void
f180de
-filter_mount_list (void)
f180de
+filter_mount_list (bool devices_only)
f180de
 {
f180de
   struct mount_entry *me;
f180de
 
f180de
-  /* Store of already-processed device numbers.  */
f180de
-  struct devlist *devlist_head = NULL;
f180de
-
f180de
   /* Sort all 'wanted' entries into the list devlist_head.  */
f180de
   for (me = mount_list; me;)
f180de
     {
6ee4d0
@@ -623,41 +620,66 @@ filter_mount_list (void)
f180de
       struct devlist *devlist;
f180de
       struct mount_entry *discard_me = NULL;
f180de
 
f180de
-      if (-1 == stat (me->me_mountdir, &buf))
f180de
+      /* Avoid stating remote file systems as that may hang.
f180de
+         On Linux we probably have me_dev populated from /proc/self/mountinfo,
f180de
+         however we still stat() in case another device was mounted later.  */
f180de
+      if ((me->me_remote && show_local_fs)
f180de
+          || -1 == stat (me->me_mountdir, &buf))
f180de
         {
f180de
-          /* Stat failed - add ME to be able to complain about it later.  */
f180de
+          /* If remote, and showing just local, add ME for filtering later.
f180de
+             If stat failed; add ME to be able to complain about it later.  */
f180de
           buf.st_dev = me->me_dev;
f180de
         }
f180de
       else
f180de
         {
f180de
-          /* If the device name is a real path name ...  */
f180de
-          if (strchr (me->me_devname, '/'))
f180de
-            {
f180de
-              /* ... try to find its device number in the devlist.  */
f180de
-              for (devlist = devlist_head; devlist; devlist = devlist->next)
f180de
-                if (devlist->dev_num == buf.st_dev)
f180de
-                  break;
f180de
+          /* If we've already seen this device...  */
f180de
+          for (devlist = device_list; devlist; devlist = devlist->next)
f180de
+            if (devlist->dev_num == buf.st_dev)
f180de
+              break;
f180de
 
f180de
-              if (devlist)
f180de
+          if (devlist)
f180de
+            {
f180de
+              if (! print_grand_total && me->me_remote && devlist->me->me_remote
f180de
+                  && ! STREQ (devlist->me->me_devname, me->me_devname))
f180de
                 {
f180de
+                  /* Don't discard remote entries with different locations,
f180de
+                     as these are more likely to be explicitly mounted.
f180de
+                     However avoid this when producing a total to give
f180de
+                     a more accurate value in that case.  */
f180de
+                }
f180de
+              else if ((strchr (me->me_devname, '/')
f180de
+                       /* let "real" devices with '/' in the name win.  */
f180de
+                        && ! strchr (devlist->me->me_devname, '/'))
f180de
+                       /* let a shorter mountdir win.  */
f180de
+                       || (strlen (devlist->me->me_mountdir)
f180de
+                           > strlen (me->me_mountdir))
f180de
+                       /* let an entry overmounted on a new device win...  */
f180de
+                       || (! STREQ (devlist->me->me_devname, me->me_devname)
f180de
+                           /* ... but only when matching an existing mnt point,
f180de
+                              to avoid problematic replacement when given
f180de
+                              inaccurate mount lists, seen with some chroot
f180de
+                              environments for example.  */
f180de
+                           && STREQ (me->me_mountdir,
f180de
+                                     devlist->me->me_mountdir)))
f180de
+                {
f180de
+                  /* Discard mount entry for existing device.  */
f180de
+                  discard_me = devlist->me;
f180de
+                  devlist->me = me;
f180de
+                }
f180de
+              else
f180de
+                {
f180de
+                  /* Discard mount entry currently being processed.  */
f180de
                   discard_me = me;
f180de
-
f180de
-                  /* Let the shorter mountdir win.  */
f180de
-                  if (! strchr (devlist->me->me_devname, '/')
f180de
-                      || (strlen (devlist->me->me_mountdir)
f180de
-                         > strlen (me->me_mountdir)))
f180de
-                    {
f180de
-                      discard_me = devlist->me;
f180de
-                      devlist->me = me;
f180de
-                    }
f180de
                 }
f180de
+
f180de
             }
f180de
         }
f180de
 
f180de
       if (discard_me)
f180de
         {
f180de
            me = me->me_next;
f180de
-           free_mount_entry (discard_me);
f180de
+           if (! devices_only)
f180de
+             free_mount_entry (discard_me);
f180de
         }
f180de
       else
f180de
         {
6ee4d0
@@ -665,28 +687,49 @@ filter_mount_list (void)
f180de
           devlist = xmalloc (sizeof *devlist);
f180de
           devlist->me = me;
f180de
           devlist->dev_num = buf.st_dev;
f180de
-          devlist->next = devlist_head;
f180de
-          devlist_head = devlist;
f180de
+          devlist->next = device_list;
f180de
+          device_list = devlist;
f180de
 
f180de
           me = me->me_next;
f180de
         }
f180de
     }
f180de
 
f180de
   /* Finally rebuild the mount_list from the devlist.  */
f180de
-  mount_list = NULL;
f180de
-  while (devlist_head)
f180de
+  if (! devices_only) {
f180de
+    mount_list = NULL;
f180de
+    while (device_list)
f180de
+      {
f180de
+        /* Add the mount entry.  */
f180de
+        me = device_list->me;
f180de
+        me->me_next = mount_list;
f180de
+        mount_list = me;
f180de
+        /* Free devlist entry and advance.  */
f180de
+        struct devlist *devlist = device_list->next;
f180de
+        free (device_list);
f180de
+        device_list = devlist;
f180de
+      }
f180de
+  }
6ee4d0
+}
6ee4d0
+
f180de
+/* Search a mount entry list for device id DEV.
f180de
+   Return the corresponding mount entry if found or NULL if not.  */
f180de
+
f180de
+static struct mount_entry const * _GL_ATTRIBUTE_PURE
f180de
+me_for_dev (dev_t dev)
f180de
+{
f180de
+  struct devlist *dl = device_list;
f180de
+
f180de
+  while (dl)
6ee4d0
     {
6ee4d0
-      /* Add the mount entry.  */
6ee4d0
-      me = devlist_head->me;
6ee4d0
-      me->me_next = mount_list;
6ee4d0
-      mount_list = me;
6ee4d0
-      /* Free devlist entry and advance.  */
6ee4d0
-      struct devlist *devlist = devlist_head->next;
6ee4d0
-      free (devlist_head);
6ee4d0
-      devlist_head = devlist;
f180de
+      if (dl->dev_num == dev)
f180de
+        return dl->me;
f180de
+      dl = dl->next;
6ee4d0
     }
f180de
+
f180de
+  return NULL;
6ee4d0
 }
6ee4d0
 
f180de
+
f180de
 /* Return true if N is a known integer value.  On many file systems,
f180de
    UINTMAX_MAX represents an unknown value; on AIX, UINTMAX_MAX - 1
f180de
    represents unknown.  Use a rule that works on AIX file systems, and
6ee4d0
@@ -856,6 +899,11 @@ get_dev (char const *disk, char const *mount_point, char const* file,
f180de
   if (!selected_fstype (fstype) || excluded_fstype (fstype))
f180de
     return;
f180de
 
f180de
+  /* Ignore relative MOUNT_POINTs, which are present for example
f180de
+     in /proc/mounts on Linux with network namespaces.  */
f180de
+  if (!force_fsu && mount_point && ! IS_ABSOLUTE_FILE_NAME (mount_point))
f180de
+    return;
f180de
+
f180de
   /* If MOUNT_POINT is NULL, then the file system is not mounted, and this
f180de
      program reports on the file system that the special file is on.
f180de
      It would be better to report on the unmounted file system,
6ee4d0
@@ -868,9 +916,43 @@ get_dev (char const *disk, char const *mount_point, char const* file,
f180de
     fsu = *force_fsu;
f180de
   else if (get_fs_usage (stat_file, disk, &fsu))
f180de
     {
f180de
-      error (0, errno, "%s", quote (stat_file));
f180de
-      exit_status = EXIT_FAILURE;
f180de
-      return;
f180de
+      /* If we can't access a system provided entry due
f180de
+         to it not being present (now), or due to permissions,
f180de
+         just output placeholder values rather than failing.  */
f180de
+      if (process_all && (errno == EACCES || errno == ENOENT))
f180de
+        {
f180de
+          if (! show_all_fs)
f180de
+            return;
f180de
+
f180de
+          fstype = "-";
f180de
+          fsu.fsu_blocksize = fsu.fsu_blocks = fsu.fsu_bfree =
f180de
+          fsu.fsu_bavail = fsu.fsu_files = fsu.fsu_ffree = UINTMAX_MAX;
f180de
+        }
f180de
+      else
f180de
+        {
f180de
+          error (0, errno, "%s", quote (stat_file));
f180de
+          exit_status = EXIT_FAILURE;
f180de
+          return;
f180de
+        }
f180de
+    }
f180de
+  else if (process_all && show_all_fs)
f180de
+    {
f180de
+      /* Ensure we don't output incorrect stats for over-mounted directories.
f180de
+         Discard stats when the device name doesn't match.  Though don't
f180de
+         discard when used and current mount entries are both remote due
f180de
+         to the possibility of aliased host names or exports.  */
f180de
+      struct stat sb;
f180de
+      if (stat (stat_file, &sb) == 0)
f180de
+        {
f180de
+          struct mount_entry const * dev_me = me_for_dev (sb.st_dev);
f180de
+          if (dev_me && ! STREQ (dev_me->me_devname, disk)
f180de
+              && (! dev_me->me_remote || ! me_remote))
f180de
+            {
f180de
+              fstype = "-";
f180de
+              fsu.fsu_blocksize = fsu.fsu_blocks = fsu.fsu_bfree =
f180de
+              fsu.fsu_bavail = fsu.fsu_files = fsu.fsu_ffree = UINTMAX_MAX;
f180de
+            }
f180de
+        }
f180de
     }
f180de
 
f180de
   if (fsu.fsu_blocks == 0 && !show_all_fs && !show_listed_fs)
6ee4d0
@@ -1275,8 +1357,7 @@ get_all_entries (void)
f180de
 {
f180de
   struct mount_entry *me;
f180de
 
f180de
-  if (!show_all_fs)
f180de
-    filter_mount_list ();
f180de
+  filter_mount_list (show_all_fs);
f180de
 
f180de
   for (me = mount_list; me; me = me->me_next)
f180de
     get_dev (me->me_devname, me->me_mountdir, NULL, NULL, me->me_type,
6ee4d0
@@ -1325,7 +1406,7 @@ or all file systems by default.\n\
6ee4d0
       emit_mandatory_arg_note ();
6ee4d0
 
6ee4d0
       fputs (_("\
6ee4d0
-  -a, --all             include dummy file systems\n\
6ee4d0
+  -a, --all             include pseudo, duplicate, inaccessible file systems\n\
6ee4d0
   -B, --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,\n\
6ee4d0
                            '-BM' prints sizes in units of 1,048,576 bytes;\n\
6ee4d0
                            see SIZE format below\n\
6ee4d0
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
6ee4d0
index 942d9a1..1df1eac 100644
6ee4d0
--- a/doc/coreutils.texi
6ee4d0
+++ b/doc/coreutils.texi
6ee4d0
@@ -11123,11 +11123,15 @@ The program accepts the following options.  Also see @ref{Common options}.
f180de
 @itemx --all
f180de
 @opindex -a
f180de
 @opindex --all
f180de
-@cindex automounter file systems
f180de
 @cindex ignore file systems
f180de
-Include in the listing dummy file systems, which
f180de
-are omitted by default.  Such file systems are typically special-purpose
f180de
-pseudo-file-systems, such as automounter entries.
f180de
+Include in the listing dummy, duplicate, or inaccessible file systems, which
f180de
+are omitted by default. Dummy file systems are typically special purpose
f180de
+pseudo file systems such as @samp{/proc}, with no associated storage.
f180de
+Duplicate file systems are local or remote file systems that are mounted
f180de
+at separate locations in the local file hierarchy, or bind mounted locations.
f180de
+Inaccessible file systems are those which are mounted but subsequently
f180de
+over-mounted by another file system at that point, or otherwise inaccessible
f180de
+due to permissions of the mount point etc.
f180de
 
f180de
 @item -B @var{size}
f180de
 @itemx --block-size=@var{size}
6ee4d0
diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh
6ee4d0
index 1e94dc0..4069604 100755
6ee4d0
--- a/tests/df/skip-duplicates.sh
6ee4d0
+++ b/tests/df/skip-duplicates.sh
f180de
@@ -2,7 +2,7 @@
f180de
 # Test df's behavior when the mount list contains duplicate entries.
f180de
 # This test is skipped on systems that lack LD_PRELOAD support; that's fine.
f180de
 
f180de
-# Copyright (C) 2012-2013 Free Software Foundation, Inc.
f180de
+# Copyright (C) 2012-2015 Free Software Foundation, Inc.
f180de
 
f180de
 # This program is free software: you can redistribute it and/or modify
f180de
 # it under the terms of the GNU General Public License as published by
f180de
@@ -21,19 +21,73 @@
f180de
 print_ver_ df
f180de
 require_gcc_shared_
f180de
 
f180de
-df || skip_ "df fails"
f180de
+# We use --local here so as to not activate
f180de
+# potentially very many remote mounts.
f180de
+df --local || skip_ 'df fails'
6ee4d0
 
6ee4d0
-# Simulate an mtab file with two entries of the same device number.
6ee4d0
-# Also add entries with unstatable mount dirs to ensure that's handled.
6ee4d0
-cat > k.c <<'EOF' || framework_failure_
f180de
+export CU_NONROOT_FS=$(df --local --output=target 2>&1 | grep /. | head -n1)
f180de
+export CU_REMOTE_FS=$(df --local --output=target 2>&1 | grep /. |
f180de
+                      tail -n+2 | head -n1)
f180de
+
f180de
+unique_entries=1
f180de
+test -z "$CU_NONROOT_FS" || unique_entries=$(expr $unique_entries + 1)
f180de
+test -z "$CU_REMOTE_FS" || unique_entries=$(expr $unique_entries + 2)
f180de
+
f180de
+grep '^#define HAVE_MNTENT_H 1' $CONFIG_HEADER > /dev/null \
f180de
+      || skip_ "no mntent.h available to confirm the interface"
f180de
+
f180de
+grep '^#define HAVE_GETMNTENT 1' $CONFIG_HEADER > /dev/null \
f180de
+      || skip_ "getmntent is not used on this system"
f180de
+
f180de
+# Simulate an mtab file to test various cases.
f180de
+cat > k.c <
f180de
+#define _GNU_SOURCE
f180de
 #include <stdio.h>
f180de
 #include <stdlib.h>
f180de
+#include <errno.h>
f180de
 #include <mntent.h>
f180de
+#include <string.h>
f180de
+#include <dlfcn.h>
f180de
+
f180de
+#define STREQ(a, b) (strcmp (a, b) == 0)
f180de
+
f180de
+FILE* fopen(const char *path, const char *mode)
f180de
+{
f180de
+  static FILE* (*fopen_func)(char const *, char const *);
f180de
+
f180de
+  /* get reference to original (libc provided) fopen */
f180de
+  if (!fopen_func)
f180de
+    {
f180de
+      fopen_func = (FILE*(*)(char const *, char const *))
f180de
+                   dlsym(RTLD_NEXT, "fopen");
f180de
+      if (!fopen_func)
f180de
+        {
f180de
+          fprintf (stderr, "Failed to find fopen()\n");
f180de
+          errno = ESRCH;
f180de
+          return NULL;
f180de
+        }
f180de
+    }
f180de
+
f180de
+  /* Returning ENOENT here will get read_file_system_list()
f180de
+     to fall back to using getmntent() below.  */
f180de
+  if (STREQ (path, "/proc/self/mountinfo"))
f180de
+    {
f180de
+      errno = ENOENT;
f180de
+      return NULL;
f180de
+    }
f180de
+  else
f180de
+    return fopen_func(path, mode);
f180de
+}
f180de
+
f180de
+#define STREQ(a, b) (strcmp (a, b) == 0)
f180de
 
f180de
 struct mntent *getmntent (FILE *fp)
f180de
 {
f180de
+  static char *nonroot_fs;
f180de
+  static char *remote_fs;
f180de
+  static int done;
f180de
+
f180de
   /* Prove that LD_PRELOAD works. */
f180de
-  static int done = 0;
f180de
   if (!done)
f180de
     {
f180de
       fclose (fopen ("x", "w"));
f180de
@@ -41,50 +95,92 @@ struct mntent *getmntent (FILE *fp)
f180de
     }
f180de
 
f180de
   static struct mntent mntents[] = {
f180de
-    {.mnt_fsname="/short",  .mnt_dir="/invalid/mount/dir"},
f180de
-    {.mnt_fsname="fsname",  .mnt_dir="/",},
f180de
-    {.mnt_fsname="/fsname", .mnt_dir="/root"},
f180de
-    {.mnt_fsname="/fsname", .mnt_dir="/"},
f180de
+    {.mnt_fsname="/short",  .mnt_dir="/invalid/mount/dir",       .mnt_opts=""},
f180de
+    {.mnt_fsname="fsname",  .mnt_dir="/",                        .mnt_opts=""},
f180de
+    {.mnt_fsname="/fsname", .mnt_dir="/.",                       .mnt_opts=""},
f180de
+    {.mnt_fsname="/fsname", .mnt_dir="/",                        .mnt_opts=""},
f180de
+    {.mnt_fsname="virtfs",  .mnt_dir="/NONROOT", .mnt_type="t1", .mnt_opts=""},
f180de
+    {.mnt_fsname="virtfs2", .mnt_dir="/NONROOT", .mnt_type="t2", .mnt_opts=""},
f180de
+    {.mnt_fsname="netns",   .mnt_dir="net:[1234567]",            .mnt_opts=""},
f180de
+    {.mnt_fsname="rem:ote1",.mnt_dir="/REMOTE",                  .mnt_opts=""},
f180de
+    {.mnt_fsname="rem:ote1",.mnt_dir="/REMOTE",                  .mnt_opts=""},
f180de
+    {.mnt_fsname="rem:ote2",.mnt_dir="/REMOTE",                  .mnt_opts=""},
f180de
   };
f180de
 
f180de
-  if (!getenv ("CU_TEST_DUPE_INVALID") && done == 1)
f180de
+  if (done == 1)
f180de
+    {
f180de
+      nonroot_fs = getenv ("CU_NONROOT_FS");
f180de
+      if (!nonroot_fs || !*nonroot_fs)
f180de
+        nonroot_fs = "/"; /* merge into / entries.  */
f180de
+
f180de
+      remote_fs = getenv ("CU_REMOTE_FS");
f180de
+    }
f180de
+
f180de
+  if (done == 1 && !getenv ("CU_TEST_DUPE_INVALID"))
f180de
     done++;  /* skip the first entry.  */
f180de
 
f180de
-  while (done++ <= 4)
f180de
+  while (done++ <= 10)
f180de
     {
f180de
-      mntents[done-2].mnt_type = "-";
f180de
+      if (!mntents[done-2].mnt_type)
f180de
+        mntents[done-2].mnt_type = "-";
f180de
+      if (!mntents[done-2].mnt_opts)
f180de
+        mntents[done-2].mnt_opts = "-";
f180de
+      if (STREQ (mntents[done-2].mnt_dir, "/NONROOT"))
f180de
+        mntents[done-2].mnt_dir = nonroot_fs;
f180de
+      if (STREQ (mntents[done-2].mnt_dir, "/REMOTE"))
f180de
+        {
f180de
+          if (!remote_fs || !*remote_fs)
f180de
+            continue;
f180de
+          else
f180de
+            mntents[done-2].mnt_dir = remote_fs;
f180de
+        }
f180de
       return &mntents[done-2];
f180de
     }
f180de
+
f180de
   return NULL;
f180de
 }
f180de
 EOF
f180de
 
f180de
 # Then compile/link it:
f180de
-gcc --std=gnu99 -shared -fPIC -ldl -O2 k.c -o k.so \
f180de
+gcc_shared_ k.c k.so \
f180de
   || framework_failure_ 'failed to build shared library'
f180de
 
f180de
 # Test if LD_PRELOAD works:
f180de
-LD_PRELOAD=./k.so df
f180de
+LD_PRELOAD=$LD_PRELOAD:./k.so df
f180de
 test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?"
f180de
 
f180de
 # The fake mtab file should only contain entries
f180de
 # having the same device number; thus the output should
f180de
-# consist of a header and one entry.
f180de
-LD_PRELOAD=./k.so df >out || fail=1
f180de
-test $(wc -l 
f180de
+# consist of a header and unique entries.
f180de
+LD_PRELOAD=$LD_PRELOAD:./k.so df -T >out || fail=1
f180de
+test $(wc -l 
6ee4d0
 
6ee4d0
-# Ensure we fail when unable to stat invalid entries
6ee4d0
-LD_PRELOAD=./k.so CU_TEST_DUPE_INVALID=1 df >out && fail=1
6ee4d0
-test $(wc -l 
f180de
+# With --total we should suppress the duplicate but separate remote file system
f180de
+LD_PRELOAD=$LD_PRELOAD:./k.so df --total >out || fail=1
f180de
+test "$CU_REMOTE_FS" && elide_remote=1 || elide_remote=0
f180de
+test $(wc -l 
f180de
+  { fail=1; cat out; }
f180de
+
f180de
+# Ensure we don't fail when unable to stat (currently) unavailable entries
f180de
+LD_PRELOAD=$LD_PRELOAD:./k.so CU_TEST_DUPE_INVALID=1 df -T >out || fail=1
f180de
+test $(wc -l 
f180de
 
f180de
 # df should also prefer "/fsname" over "fsname"
f180de
-test $(grep -c '/fsname' 
f180de
-# ... and "/fsname" with '/' as Mounted on over '/root'
f180de
-test $(grep -c '/root' 
f180de
+if test "$unique_entries" = 2; then
f180de
+  test $(grep -c '/fsname' 
f180de
+  # ... and "/fsname" with '/' as Mounted on over '/.'
f180de
+  test $(grep -cF '/.' 
f180de
+fi
f180de
+
f180de
+# df should use the last seen devname (mnt_fsname) and devtype (mnt_type)
f180de
+test $(grep -c 'virtfs2.*t2' 
f180de
 
f180de
 # Ensure that filtering duplicates does not affect -a processing.
f180de
-LD_PRELOAD=./k.so df -a >out || fail=1
f180de
-test $(wc -l 
f180de
+LD_PRELOAD=$LD_PRELOAD:./k.so df -a >out || fail=1
f180de
+total_fs=6; test "$CU_REMOTE_FS" && total_fs=$(expr $total_fs + 3)
f180de
+test $(wc -l 
f180de
+# Ensure placeholder "-" values used for the eclipsed "virtfs"
f180de
+test $(grep -c 'virtfs *-' 
f180de
 
f180de
 # Ensure that filtering duplicates does not affect
f180de
 # argument processing (now without the fake getmntent()).
6ee4d0
diff --git a/init.cfg b/init.cfg
6ee4d0
index 360d4da..16f9813 100644
6ee4d0
--- a/init.cfg
6ee4d0
+++ b/init.cfg
f180de
@@ -472,6 +472,18 @@ require_sparse_support_()
f180de
   fi
f180de
 }
f180de
 
f180de
+# Compile a shared lib using the GCC options for doing so.
f180de
+# Pass input and output file as parameters respectively.
f180de
+# Any other optional parmeters are passed to $CC.
f180de
+gcc_shared_()
f180de
+{
f180de
+  local in=$1
f180de
+  local out=$2
f180de
+  shift 2 || return 1
f180de
+
f180de
+  $CC -Wall -shared --std=gnu99 -fPIC -O2 $* "$in" -o "$out" -ldl
f180de
+}
f180de
+
f180de
 # There are a myriad of ways to build shared libs,
f180de
 # so we only consider running tests requiring shared libs,
f180de
 # on platforms that support building them as follows.