/* mountlist.c -- return a list of mounted file systems
- Copyright (C) 1991, 1992, 1997-2009 Free Software Foundation, Inc.
+ Copyright (C) 1991-1992, 1997-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
# include <sys/vfs.h>
#endif
+#ifdef MOUNTED_INTERIX_STATVFS /* Interix. */
+# include <sys/statvfs.h>
+# include <dirent.h>
+#endif
+
#ifdef DOLPHIN
/* So special that it's not worth putting this in autoconf. */
# undef MOUNTED_FREAD_FSTYP
#undef MNT_IGNORE
#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT
-# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
+# define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE)
#else
# define MNT_IGNORE(M) 0
#endif
#undef opendir
#undef closedir
-#ifndef ME_DUMMY
-# define ME_DUMMY(Fs_name, Fs_type) \
- (strcmp (Fs_type, "autofs") == 0 \
- || strcmp (Fs_type, "none") == 0 \
- || strcmp (Fs_type, "proc") == 0 \
- || strcmp (Fs_type, "subfs") == 0 \
- /* for NetBSD 3.0 */ \
- || strcmp (Fs_type, "kernfs") == 0 \
- /* for Irix 6.5 */ \
- || strcmp (Fs_type, "ignore") == 0)
+#define ME_DUMMY_0(Fs_name, Fs_type) \
+ (strcmp (Fs_type, "autofs") == 0 \
+ || strcmp (Fs_type, "proc") == 0 \
+ || strcmp (Fs_type, "subfs") == 0 \
+ /* for NetBSD 3.0 */ \
+ || strcmp (Fs_type, "kernfs") == 0 \
+ /* for Irix 6.5 */ \
+ || strcmp (Fs_type, "ignore") == 0)
+
+/* Historically, we have marked as "dummy" any file system of type "none",
+ but now that programs like du need to know about bind-mounted directories,
+ we grant an exception to any with "bind" in its list of mount options.
+ I.e., those are *not* dummy entries. */
+#ifdef MOUNTED_GETMNTENT1
+# define ME_DUMMY(Fs_name, Fs_type, Fs_ent) \
+ (ME_DUMMY_0 (Fs_name, Fs_type) \
+ || (strcmp (Fs_type, "none") == 0 \
+ && !hasmntopt (Fs_ent, "bind")))
+#else
+# define ME_DUMMY(Fs_name, Fs_type) \
+ (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0)
+#endif
+
+#ifdef __CYGWIN__
+# include <windows.h>
+# define ME_REMOTE me_remote
+/* All cygwin mount points include ':' or start with '//'; so it
+ requires a native Windows call to determine remote disks. */
+static bool
+me_remote (char const *fs_name, char const *fs_type _GL_UNUSED)
+{
+ if (fs_name[0] && fs_name[1] == ':')
+ {
+ char drive[4];
+ sprintf (drive, "%c:\\", fs_name[0]);
+ switch (GetDriveType (drive))
+ {
+ case DRIVE_REMOVABLE:
+ case DRIVE_FIXED:
+ case DRIVE_CDROM:
+ case DRIVE_RAMDISK:
+ return false;
+ }
+ }
+ return true;
+}
#endif
#ifndef ME_REMOTE
-/* A file system is `remote' if its Fs_name contains a `:'
- or if (it is of type (smbfs or cifs) and its Fs_name starts with `//'). */
+/* A file system is "remote" if its Fs_name contains a ':'
+ or if (it is of type (smbfs or cifs) and its Fs_name starts with '//'). */
# define ME_REMOTE(Fs_name, Fs_type) \
(strchr (Fs_name, ':') != NULL \
|| ((Fs_name)[0] == '/' \
if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0)
return NULL;
- for (p = mntlist; p; p = p->next) {
- mnt = p->ment;
- me = xmalloc (sizeof *me);
- me->me_devname = xstrdup (mnt->mnt_fsname);
- me->me_mountdir = xstrdup (mnt->mnt_dir);
- me->me_type = xstrdup (mnt->mnt_type);
- me->me_type_malloced = 1;
- me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
- me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
- me->me_dev = -1;
- *mtail = me;
- mtail = &me->me_next;
- }
+ for (p = mntlist; p; p = p->next)
+ {
+ mnt = p->ment;
+ me = xmalloc (sizeof *me);
+ me->me_devname = xstrdup (mnt->mnt_fsname);
+ me->me_mountdir = xstrdup (mnt->mnt_dir);
+ me->me_type = xstrdup (mnt->mnt_type);
+ me->me_type_malloced = 1;
+ me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
+ me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
+ me->me_dev = -1;
+ *mtail = me;
+ mtail = &me->me_next;
+ }
freemntlist (mntlist);
}
#endif
me->me_mountdir = xstrdup (mnt->mnt_dir);
me->me_type = xstrdup (mnt->mnt_type);
me->me_type_malloced = 1;
- me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
+ me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
me->me_dev = dev_from_mount_options (mnt->mnt_opts);
break;
me = xmalloc (sizeof *me);
- me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name);
+ me->me_devname = xstrdup (fi.device_name[0] != '\0'
+ ? fi.device_name : fi.fsh_name);
me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name);
me->me_type = xstrdup (fi.fsh_name);
me->me_type_malloced = 1;
size_t bufsize;
struct statfs *stats;
- numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT);
+ numsys = getfsstat (NULL, 0L, MNT_NOWAIT);
if (numsys < 0)
- return (NULL);
+ return NULL;
if (SIZE_MAX / sizeof *stats <= numsys)
xalloc_die ();
if (numsys < 0)
{
free (stats);
- return (NULL);
+ return NULL;
}
for (counter = 0; counter < numsys; counter++)
#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */
{
struct mntent **mnttbl = getmnttbl (), **ent;
- for (ent=mnttbl;*ent;ent++)
+ for (ent = mnttbl; *ent; ent++)
{
me = xmalloc (sizeof *me);
- me->me_devname = xstrdup ( (*ent)->mt_resource);
- me->me_mountdir = xstrdup ( (*ent)->mt_directory);
+ me->me_devname = xstrdup ((*ent)->mt_resource);
+ me->me_mountdir = xstrdup ((*ent)->mt_directory);
me->me_type = xstrdup ((*ent)->mt_fstype);
me->me_type_malloced = 1;
me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
}
#endif /* MOUNTED_VMOUNT. */
+#ifdef MOUNTED_INTERIX_STATVFS
+ {
+ DIR *dirp = opendir ("/dev/fs");
+ char node[9 + NAME_MAX];
+
+ if (!dirp)
+ goto free_then_fail;
+
+ while (1)
+ {
+ struct statvfs dev;
+ struct dirent entry;
+ struct dirent *result;
+
+ if (readdir_r (dirp, &entry, &result) || result == NULL)
+ break;
+
+ strcpy (node, "/dev/fs/");
+ strcat (node, entry.d_name);
+
+ if (statvfs (node, &dev) == 0)
+ {
+ me = xmalloc (sizeof *me);
+ me->me_devname = xstrdup (dev.f_mntfromname);
+ me->me_mountdir = xstrdup (dev.f_mntonname);
+ me->me_type = xstrdup (dev.f_fstypename);
+ me->me_type_malloced = 1;
+ me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
+ me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
+ me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
+
+ /* Add to the linked list. */
+ *mtail = me;
+ mtail = &me->me_next;
+ }
+ }
+ }
+#endif /* MOUNTED_INTERIX_STATVFS */
+
*mtail = NULL;
return mount_list;