X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fmountlist.c;h=8fb7e9ab747d5cf17e0964073aeeb6284215c268;hb=7517e2fd5e24f47eed66f8390d49f807555f8770;hp=ccb08dde6cb5dfdcc2f8b5e9774780afa3c409d3;hpb=b2e2010c7c902235b5efb5bd3c6529f61b093aa4;p=gnulib.git diff --git a/lib/mountlist.c b/lib/mountlist.c index ccb08dde6..8fb7e9ab7 100644 --- a/lib/mountlist.c +++ b/lib/mountlist.c @@ -1,6 +1,6 @@ /* mountlist.c -- return a list of mounted file systems - Copyright (C) 1991-1992, 1997-2010 Free Software Foundation, Inc. + Copyright (C) 1991-1992, 1997-2013 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 @@ -112,6 +112,11 @@ # include #endif +#ifdef MOUNTED_INTERIX_STATVFS /* Interix. */ +# include +# include +#endif + #ifdef DOLPHIN /* So special that it's not worth putting this in autoconf. */ # undef MOUNTED_FREAD_FSTYP @@ -125,7 +130,7 @@ #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 @@ -144,21 +149,66 @@ #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 Linux 2.6/3.x */ \ + || strcmp (Fs_type, "debugfs") == 0 \ + || strcmp (Fs_type, "devpts") == 0 \ + || strcmp (Fs_type, "fusectl") == 0 \ + || strcmp (Fs_type, "mqueue") == 0 \ + || strcmp (Fs_type, "rpc_pipefs") == 0 \ + || strcmp (Fs_type, "sysfs") == 0 \ + /* FreeBSD, Linux 2.4 */ \ + || strcmp (Fs_type, "devfs") == 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 +# 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] == '/' \ @@ -354,19 +404,20 @@ read_file_system_list (bool need_fs_type) 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 @@ -388,7 +439,7 @@ read_file_system_list (bool need_fs_type) 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); @@ -564,7 +615,8 @@ read_file_system_list (bool need_fs_type) 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; @@ -594,9 +646,9 @@ read_file_system_list (bool need_fs_type) 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 (); @@ -607,7 +659,7 @@ read_file_system_list (bool need_fs_type) if (numsys < 0) { free (stats); - return (NULL); + return NULL; } for (counter = 0; counter < numsys; counter++) @@ -693,11 +745,11 @@ read_file_system_list (bool need_fs_type) #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); @@ -854,6 +906,45 @@ read_file_system_list (bool need_fs_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;