diff options
Diffstat (limited to 'gl/mountlist.c')
| -rw-r--r-- | gl/mountlist.c | 486 |
1 files changed, 312 insertions, 174 deletions
diff --git a/gl/mountlist.c b/gl/mountlist.c index 30f42861..6d384812 100644 --- a/gl/mountlist.c +++ b/gl/mountlist.c | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | /* mountlist.c -- return a list of mounted file systems | 1 | /* mountlist.c -- return a list of mounted file systems |
| 2 | 2 | ||
| 3 | Copyright (C) 1991-1992, 1997-2013 Free Software Foundation, Inc. | 3 | Copyright (C) 1991-1992, 1997-2023 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify | 5 | This program is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
| 7 | the Free Software Foundation; either version 3 of the License, or | 7 | the Free Software Foundation, either version 3 of the License, or |
| 8 | (at your option) any later version. | 8 | (at your option) any later version. |
| 9 | 9 | ||
| 10 | This program is distributed in the hope that it will be useful, | 10 | This program is distributed in the hope that it will be useful, |
| @@ -13,7 +13,7 @@ | |||
| 13 | GNU General Public License for more details. | 13 | GNU General Public License for more details. |
| 14 | 14 | ||
| 15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #include <config.h> | 18 | #include <config.h> |
| 19 | 19 | ||
| @@ -37,7 +37,13 @@ | |||
| 37 | # include <sys/param.h> | 37 | # include <sys/param.h> |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | #if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */ | 40 | #if MAJOR_IN_MKDEV |
| 41 | # include <sys/mkdev.h> | ||
| 42 | #elif MAJOR_IN_SYSMACROS | ||
| 43 | # include <sys/sysmacros.h> | ||
| 44 | #endif | ||
| 45 | |||
| 46 | #if defined MOUNTED_GETFSSTAT /* OSF/1, also (obsolete) Apple Darwin 1.3 */ | ||
| 41 | # if HAVE_SYS_UCRED_H | 47 | # if HAVE_SYS_UCRED_H |
| 42 | # include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS, | 48 | # include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS, |
| 43 | NGROUPS is used as an array dimension in ucred.h */ | 49 | NGROUPS is used as an array dimension in ucred.h */ |
| @@ -56,102 +62,104 @@ | |||
| 56 | # endif | 62 | # endif |
| 57 | #endif /* MOUNTED_GETFSSTAT */ | 63 | #endif /* MOUNTED_GETFSSTAT */ |
| 58 | 64 | ||
| 59 | #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ | 65 | #ifdef MOUNTED_GETMNTENT1 /* glibc, HP-UX, IRIX, Cygwin, Android, |
| 66 | also (obsolete) 4.3BSD, SunOS */ | ||
| 60 | # include <mntent.h> | 67 | # include <mntent.h> |
| 61 | # if !defined MOUNTED | 68 | # include <sys/types.h> |
| 69 | # if defined __ANDROID__ /* Android */ | ||
| 70 | /* Bionic versions from between 2014-01-09 and 2015-01-08 define MOUNTED to | ||
| 71 | an incorrect value; older Bionic versions don't define it at all. */ | ||
| 72 | # undef MOUNTED | ||
| 73 | # define MOUNTED "/proc/mounts" | ||
| 74 | # elif !defined MOUNTED | ||
| 62 | # if defined _PATH_MOUNTED /* GNU libc */ | 75 | # if defined _PATH_MOUNTED /* GNU libc */ |
| 63 | # define MOUNTED _PATH_MOUNTED | 76 | # define MOUNTED _PATH_MOUNTED |
| 64 | # endif | 77 | # endif |
| 65 | # if defined MNT_MNTTAB /* HP-UX. */ | 78 | # if defined MNT_MNTTAB /* HP-UX. */ |
| 66 | # define MOUNTED MNT_MNTTAB | 79 | # define MOUNTED MNT_MNTTAB |
| 67 | # endif | 80 | # endif |
| 68 | # if defined MNTTABNAME /* Dynix. */ | ||
| 69 | # define MOUNTED MNTTABNAME | ||
| 70 | # endif | ||
| 71 | # endif | 81 | # endif |
| 72 | #endif | 82 | #endif |
| 73 | 83 | ||
| 74 | #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ | 84 | #ifdef MOUNTED_GETMNTINFO /* Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD */ |
| 75 | # include <sys/mount.h> | 85 | # include <sys/mount.h> |
| 76 | #endif | 86 | #endif |
| 77 | 87 | ||
| 78 | #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ | 88 | #ifdef MOUNTED_GETMNTINFO2 /* NetBSD, Minix */ |
| 79 | # include <sys/statvfs.h> | 89 | # include <sys/statvfs.h> |
| 80 | #endif | 90 | #endif |
| 81 | 91 | ||
| 82 | #ifdef MOUNTED_GETMNT /* Ultrix. */ | 92 | #ifdef MOUNTED_FS_STAT_DEV /* Haiku, also (obsolete) BeOS */ |
| 83 | # include <sys/mount.h> | ||
| 84 | # include <sys/fs_types.h> | ||
| 85 | #endif | ||
| 86 | |||
| 87 | #ifdef MOUNTED_FS_STAT_DEV /* BeOS. */ | ||
| 88 | # include <fs_info.h> | 93 | # include <fs_info.h> |
| 89 | # include <dirent.h> | 94 | # include <dirent.h> |
| 90 | #endif | 95 | #endif |
| 91 | 96 | ||
| 92 | #ifdef MOUNTED_FREAD /* SVR2. */ | 97 | #ifdef MOUNTED_FREAD_FSTYP /* (obsolete) SVR3 */ |
| 93 | # include <mnttab.h> | ||
| 94 | #endif | ||
| 95 | |||
| 96 | #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */ | ||
| 97 | # include <mnttab.h> | 98 | # include <mnttab.h> |
| 98 | # include <sys/fstyp.h> | 99 | # include <sys/fstyp.h> |
| 99 | # include <sys/statfs.h> | 100 | # include <sys/statfs.h> |
| 100 | #endif | 101 | #endif |
| 101 | 102 | ||
| 102 | #ifdef MOUNTED_LISTMNTENT | 103 | #ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */ |
| 103 | # include <mntent.h> | 104 | # include <sys/mnttab.h> |
| 104 | #endif | 105 | #endif |
| 105 | 106 | ||
| 106 | #ifdef MOUNTED_GETMNTENT2 /* SVR4. */ | 107 | #ifdef MOUNTED_GETMNTENT2 /* Solaris < 8, also (obsolete) SVR4 */ |
| 107 | # include <sys/mnttab.h> | 108 | # include <sys/mnttab.h> |
| 108 | #endif | 109 | #endif |
| 109 | 110 | ||
| 110 | #ifdef MOUNTED_VMOUNT /* AIX. */ | 111 | #ifdef MOUNTED_VMOUNT /* AIX */ |
| 111 | # include <fshelp.h> | 112 | # include <fshelp.h> |
| 112 | # include <sys/vfs.h> | 113 | # include <sys/vfs.h> |
| 113 | #endif | 114 | #endif |
| 114 | 115 | ||
| 115 | #ifdef MOUNTED_INTERIX_STATVFS /* Interix. */ | 116 | #ifdef MOUNTED_INTERIX_STATVFS /* Interix */ |
| 116 | # include <sys/statvfs.h> | 117 | # include <sys/statvfs.h> |
| 117 | # include <dirent.h> | 118 | # include <dirent.h> |
| 118 | #endif | 119 | #endif |
| 119 | 120 | ||
| 120 | #ifdef DOLPHIN | ||
| 121 | /* So special that it's not worth putting this in autoconf. */ | ||
| 122 | # undef MOUNTED_FREAD_FSTYP | ||
| 123 | # define MOUNTED_GETMNTTBL | ||
| 124 | #endif | ||
| 125 | |||
| 126 | #if HAVE_SYS_MNTENT_H | 121 | #if HAVE_SYS_MNTENT_H |
| 127 | /* This is to get MNTOPT_IGNORE on e.g. SVR4. */ | 122 | /* This is to get MNTOPT_IGNORE on e.g. SVR4. */ |
| 128 | # include <sys/mntent.h> | 123 | # include <sys/mntent.h> |
| 129 | #endif | 124 | #endif |
| 130 | 125 | ||
| 126 | #ifdef MOUNTED_GETMNTENT1 | ||
| 127 | # if !HAVE_SETMNTENT /* Android <= 4.4 */ | ||
| 128 | # define setmntent(fp,mode) fopen (fp, mode "e") | ||
| 129 | # endif | ||
| 130 | # if !HAVE_ENDMNTENT /* Android <= 4.4 */ | ||
| 131 | # define endmntent(fp) fclose (fp) | ||
| 132 | # endif | ||
| 133 | #endif | ||
| 134 | |||
| 131 | #ifndef HAVE_HASMNTOPT | 135 | #ifndef HAVE_HASMNTOPT |
| 132 | # define hasmntopt(mnt, opt) ((char *) 0) | 136 | # define hasmntopt(mnt, opt) ((char *) 0) |
| 133 | #endif | 137 | #endif |
| 134 | 138 | ||
| 135 | #undef MNT_IGNORE | 139 | #undef MNT_IGNORE |
| 136 | #ifdef MNTOPT_IGNORE | 140 | #ifdef MNTOPT_IGNORE |
| 137 | # define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE) | 141 | # if defined __sun && defined __SVR4 |
| 142 | /* Solaris defines hasmntopt(struct mnttab *, char *) | ||
| 143 | while it is otherwise hasmntopt(struct mnttab *, const char *). */ | ||
| 144 | # define MNT_IGNORE(M) hasmntopt (M, (char *) MNTOPT_IGNORE) | ||
| 145 | # else | ||
| 146 | # define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE) | ||
| 147 | # endif | ||
| 138 | #else | 148 | #else |
| 139 | # define MNT_IGNORE(M) 0 | 149 | # define MNT_IGNORE(M) 0 |
| 140 | #endif | 150 | #endif |
| 141 | 151 | ||
| 142 | #if USE_UNLOCKED_IO | 152 | /* Each of the FILE streams in this file is only used in a single thread. */ |
| 143 | # include "unlocked-io.h" | 153 | #include "unlocked-io.h" |
| 144 | #endif | ||
| 145 | |||
| 146 | /* The results of open() in this file are not used with fchdir, | ||
| 147 | therefore save some unnecessary work in fchdir.c. */ | ||
| 148 | #undef open | ||
| 149 | #undef close | ||
| 150 | 154 | ||
| 151 | /* The results of opendir() in this file are not used with dirfd and fchdir, | 155 | /* The results of opendir() in this file are not used with dirfd and fchdir, |
| 152 | therefore save some unnecessary work in fchdir.c. */ | 156 | therefore save some unnecessary work in fchdir.c. */ |
| 153 | #undef opendir | 157 | #ifdef GNULIB_defined_opendir |
| 154 | #undef closedir | 158 | # undef opendir |
| 159 | #endif | ||
| 160 | #ifdef GNULIB_defined_closedir | ||
| 161 | # undef closedir | ||
| 162 | #endif | ||
| 155 | 163 | ||
| 156 | #define ME_DUMMY_0(Fs_name, Fs_type) \ | 164 | #define ME_DUMMY_0(Fs_name, Fs_type) \ |
| 157 | (strcmp (Fs_type, "autofs") == 0 \ | 165 | (strcmp (Fs_type, "autofs") == 0 \ |
| @@ -161,6 +169,7 @@ | |||
| 161 | || strcmp (Fs_type, "debugfs") == 0 \ | 169 | || strcmp (Fs_type, "debugfs") == 0 \ |
| 162 | || strcmp (Fs_type, "devpts") == 0 \ | 170 | || strcmp (Fs_type, "devpts") == 0 \ |
| 163 | || strcmp (Fs_type, "fusectl") == 0 \ | 171 | || strcmp (Fs_type, "fusectl") == 0 \ |
| 172 | || strcmp (Fs_type, "fuse.portal") == 0 \ | ||
| 164 | || strcmp (Fs_type, "mqueue") == 0 \ | 173 | || strcmp (Fs_type, "mqueue") == 0 \ |
| 165 | || strcmp (Fs_type, "rpc_pipefs") == 0 \ | 174 | || strcmp (Fs_type, "rpc_pipefs") == 0 \ |
| 166 | || strcmp (Fs_type, "sysfs") == 0 \ | 175 | || strcmp (Fs_type, "sysfs") == 0 \ |
| @@ -176,10 +185,9 @@ | |||
| 176 | we grant an exception to any with "bind" in its list of mount options. | 185 | we grant an exception to any with "bind" in its list of mount options. |
| 177 | I.e., those are *not* dummy entries. */ | 186 | I.e., those are *not* dummy entries. */ |
| 178 | #ifdef MOUNTED_GETMNTENT1 | 187 | #ifdef MOUNTED_GETMNTENT1 |
| 179 | # define ME_DUMMY(Fs_name, Fs_type, Fs_ent) \ | 188 | # define ME_DUMMY(Fs_name, Fs_type, Bind) \ |
| 180 | (ME_DUMMY_0 (Fs_name, Fs_type) \ | 189 | (ME_DUMMY_0 (Fs_name, Fs_type) \ |
| 181 | || (strcmp (Fs_type, "none") == 0 \ | 190 | || (strcmp (Fs_type, "none") == 0 && !Bind)) |
| 182 | && !hasmntopt (Fs_ent, "bind"))) | ||
| 183 | #else | 191 | #else |
| 184 | # define ME_DUMMY(Fs_name, Fs_type) \ | 192 | # define ME_DUMMY(Fs_name, Fs_type) \ |
| 185 | (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0) | 193 | (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0) |
| @@ -187,11 +195,14 @@ | |||
| 187 | 195 | ||
| 188 | #ifdef __CYGWIN__ | 196 | #ifdef __CYGWIN__ |
| 189 | # include <windows.h> | 197 | # include <windows.h> |
| 198 | /* Don't assume that UNICODE is not defined. */ | ||
| 199 | # undef GetDriveType | ||
| 200 | # define GetDriveType GetDriveTypeA | ||
| 190 | # define ME_REMOTE me_remote | 201 | # define ME_REMOTE me_remote |
| 191 | /* All cygwin mount points include ':' or start with '//'; so it | 202 | /* All cygwin mount points include ':' or start with '//'; so it |
| 192 | requires a native Windows call to determine remote disks. */ | 203 | requires a native Windows call to determine remote disks. */ |
| 193 | static bool | 204 | static bool |
| 194 | me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) | 205 | me_remote (char const *fs_name, _GL_UNUSED char const *fs_type) |
| 195 | { | 206 | { |
| 196 | if (fs_name[0] && fs_name[1] == ':') | 207 | if (fs_name[0] && fs_name[1] == ':') |
| 197 | { | 208 | { |
| @@ -212,16 +223,30 @@ me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) | |||
| 212 | 223 | ||
| 213 | #ifndef ME_REMOTE | 224 | #ifndef ME_REMOTE |
| 214 | /* A file system is "remote" if its Fs_name contains a ':' | 225 | /* A file system is "remote" if its Fs_name contains a ':' |
| 215 | or if (it is of type (smbfs or cifs) and its Fs_name starts with '//'). */ | 226 | or if (it is of type (smbfs or cifs) and its Fs_name starts with '//') |
| 227 | or if it is of any other of the listed types | ||
| 228 | or Fs_name is equal to "-hosts" (used by autofs to mount remote fs). | ||
| 229 | "VM" file systems like prl_fs or vboxsf are not considered remote here. */ | ||
| 216 | # define ME_REMOTE(Fs_name, Fs_type) \ | 230 | # define ME_REMOTE(Fs_name, Fs_type) \ |
| 217 | (strchr (Fs_name, ':') != NULL \ | 231 | (strchr (Fs_name, ':') != NULL \ |
| 218 | || ((Fs_name)[0] == '/' \ | 232 | || ((Fs_name)[0] == '/' \ |
| 219 | && (Fs_name)[1] == '/' \ | 233 | && (Fs_name)[1] == '/' \ |
| 220 | && (strcmp (Fs_type, "smbfs") == 0 \ | 234 | && (strcmp (Fs_type, "smbfs") == 0 \ |
| 221 | || strcmp (Fs_type, "cifs") == 0))) | 235 | || strcmp (Fs_type, "smb3") == 0 \ |
| 236 | || strcmp (Fs_type, "cifs") == 0)) \ | ||
| 237 | || strcmp (Fs_type, "acfs") == 0 \ | ||
| 238 | || strcmp (Fs_type, "afs") == 0 \ | ||
| 239 | || strcmp (Fs_type, "coda") == 0 \ | ||
| 240 | || strcmp (Fs_type, "auristorfs") == 0 \ | ||
| 241 | || strcmp (Fs_type, "fhgfs") == 0 \ | ||
| 242 | || strcmp (Fs_type, "gpfs") == 0 \ | ||
| 243 | || strcmp (Fs_type, "ibrix") == 0 \ | ||
| 244 | || strcmp (Fs_type, "ocfs2") == 0 \ | ||
| 245 | || strcmp (Fs_type, "vxfs") == 0 \ | ||
| 246 | || strcmp ("-hosts", Fs_name) == 0) | ||
| 222 | #endif | 247 | #endif |
| 223 | 248 | ||
| 224 | #if MOUNTED_GETMNTINFO | 249 | #if MOUNTED_GETMNTINFO /* Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD */ |
| 225 | 250 | ||
| 226 | # if ! HAVE_STRUCT_STATFS_F_FSTYPENAME | 251 | # if ! HAVE_STRUCT_STATFS_F_FSTYPENAME |
| 227 | static char * | 252 | static char * |
| @@ -331,7 +356,7 @@ fsp_to_string (const struct statfs *fsp) | |||
| 331 | 356 | ||
| 332 | #endif /* MOUNTED_GETMNTINFO */ | 357 | #endif /* MOUNTED_GETMNTINFO */ |
| 333 | 358 | ||
| 334 | #ifdef MOUNTED_VMOUNT /* AIX. */ | 359 | #ifdef MOUNTED_VMOUNT /* AIX */ |
| 335 | static char * | 360 | static char * |
| 336 | fstype_to_string (int t) | 361 | fstype_to_string (int t) |
| 337 | { | 362 | { |
| @@ -382,6 +407,46 @@ dev_from_mount_options (char const *mount_options) | |||
| 382 | 407 | ||
| 383 | #endif | 408 | #endif |
| 384 | 409 | ||
| 410 | #if defined MOUNTED_GETMNTENT1 && (defined __linux__ || defined __ANDROID__) /* GNU/Linux, Android */ | ||
| 411 | |||
| 412 | /* Unescape the paths in mount tables. | ||
| 413 | STR is updated in place. */ | ||
| 414 | |||
| 415 | static void | ||
| 416 | unescape_tab (char *str) | ||
| 417 | { | ||
| 418 | size_t i, j = 0; | ||
| 419 | size_t len = strlen (str) + 1; | ||
| 420 | for (i = 0; i < len; i++) | ||
| 421 | { | ||
| 422 | if (str[i] == '\\' && (i + 4 < len) | ||
| 423 | && str[i + 1] >= '0' && str[i + 1] <= '3' | ||
| 424 | && str[i + 2] >= '0' && str[i + 2] <= '7' | ||
| 425 | && str[i + 3] >= '0' && str[i + 3] <= '7') | ||
| 426 | { | ||
| 427 | str[j++] = (str[i + 1] - '0') * 64 + | ||
| 428 | (str[i + 2] - '0') * 8 + | ||
| 429 | (str[i + 3] - '0'); | ||
| 430 | i += 3; | ||
| 431 | } | ||
| 432 | else | ||
| 433 | str[j++] = str[i]; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | /* Find the next space in STR, terminate the string there in place, | ||
| 438 | and return that position. Otherwise return NULL. */ | ||
| 439 | |||
| 440 | static char * | ||
| 441 | terminate_at_blank (char *str) | ||
| 442 | { | ||
| 443 | char *s = strchr (str, ' '); | ||
| 444 | if (s) | ||
| 445 | *s = '\0'; | ||
| 446 | return s; | ||
| 447 | } | ||
| 448 | #endif | ||
| 449 | |||
| 385 | /* Return a list of the currently mounted file systems, or NULL on error. | 450 | /* Return a list of the currently mounted file systems, or NULL on error. |
| 386 | Add each entry to the tail of the list so that they stay in order. | 451 | Add each entry to the tail of the list so that they stay in order. |
| 387 | If NEED_FS_TYPE is true, ensure that the file system type fields in | 452 | If NEED_FS_TYPE is true, ensure that the file system type fields in |
| @@ -395,69 +460,141 @@ read_file_system_list (bool need_fs_type) | |||
| 395 | struct mount_entry **mtail = &mount_list; | 460 | struct mount_entry **mtail = &mount_list; |
| 396 | (void) need_fs_type; | 461 | (void) need_fs_type; |
| 397 | 462 | ||
| 398 | #ifdef MOUNTED_LISTMNTENT | 463 | #ifdef MOUNTED_GETMNTENT1 /* glibc, HP-UX, IRIX, Cygwin, Android, |
| 464 | also (obsolete) 4.3BSD, SunOS */ | ||
| 399 | { | 465 | { |
| 400 | struct tabmntent *mntlist, *p; | 466 | FILE *fp; |
| 401 | struct mntent *mnt; | ||
| 402 | struct mount_entry *me; | ||
| 403 | |||
| 404 | /* the third and fourth arguments could be used to filter mounts, | ||
| 405 | but Crays doesn't seem to have any mounts that we want to | ||
| 406 | remove. Specifically, automount create normal NFS mounts. | ||
| 407 | */ | ||
| 408 | 467 | ||
| 409 | if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0) | 468 | # if defined __linux__ || defined __ANDROID__ |
| 410 | return NULL; | 469 | /* Try parsing mountinfo first, as that make device IDs available. |
| 411 | for (p = mntlist; p; p = p->next) | 470 | Note we could use libmount routines to simplify this parsing a little |
| 471 | (and that code is in previous versions of this function), however | ||
| 472 | libmount depends on libselinux which pulls in many dependencies. */ | ||
| 473 | char const *mountinfo = "/proc/self/mountinfo"; | ||
| 474 | fp = fopen (mountinfo, "re"); | ||
| 475 | if (fp != NULL) | ||
| 412 | { | 476 | { |
| 413 | mnt = p->ment; | 477 | char *line = NULL; |
| 414 | me = xmalloc (sizeof *me); | 478 | size_t buf_size = 0; |
| 415 | me->me_devname = xstrdup (mnt->mnt_fsname); | ||
| 416 | me->me_mountdir = xstrdup (mnt->mnt_dir); | ||
| 417 | me->me_type = xstrdup (mnt->mnt_type); | ||
| 418 | me->me_type_malloced = 1; | ||
| 419 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
| 420 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
| 421 | me->me_dev = -1; | ||
| 422 | *mtail = me; | ||
| 423 | mtail = &me->me_next; | ||
| 424 | } | ||
| 425 | freemntlist (mntlist); | ||
| 426 | } | ||
| 427 | #endif | ||
| 428 | 479 | ||
| 429 | #ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ | 480 | while (getline (&line, &buf_size, fp) != -1) |
| 430 | { | 481 | { |
| 431 | struct mntent *mnt; | 482 | unsigned int devmaj, devmin; |
| 432 | char const *table = MOUNTED; | 483 | int rc, mntroot_s; |
| 433 | FILE *fp; | ||
| 434 | 484 | ||
| 435 | fp = setmntent (table, "r"); | 485 | rc = sscanf(line, "%*u " /* id - discarded */ |
| 436 | if (fp == NULL) | 486 | "%*u " /* parent - discarded */ |
| 437 | return NULL; | 487 | "%u:%u " /* dev major:minor */ |
| 488 | "%n", /* mountroot (start) */ | ||
| 489 | &devmaj, &devmin, | ||
| 490 | &mntroot_s); | ||
| 438 | 491 | ||
| 439 | while ((mnt = getmntent (fp))) | 492 | if (rc != 2 && rc != 3) /* 3 if %n included in count. */ |
| 440 | { | 493 | continue; |
| 441 | me = xmalloc (sizeof *me); | ||
| 442 | me->me_devname = xstrdup (mnt->mnt_fsname); | ||
| 443 | me->me_mountdir = xstrdup (mnt->mnt_dir); | ||
| 444 | me->me_type = xstrdup (mnt->mnt_type); | ||
| 445 | me->me_type_malloced = 1; | ||
| 446 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt); | ||
| 447 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
| 448 | me->me_dev = dev_from_mount_options (mnt->mnt_opts); | ||
| 449 | 494 | ||
| 450 | /* Add to the linked list. */ | 495 | /* find end of MNTROOT. */ |
| 451 | *mtail = me; | 496 | char *mntroot = line + mntroot_s; |
| 452 | mtail = &me->me_next; | 497 | char *blank = terminate_at_blank (mntroot); |
| 498 | if (! blank) | ||
| 499 | continue; | ||
| 500 | |||
| 501 | /* find end of TARGET. */ | ||
| 502 | char *target = blank + 1; | ||
| 503 | blank = terminate_at_blank (target); | ||
| 504 | if (! blank) | ||
| 505 | continue; | ||
| 506 | |||
| 507 | /* skip optional fields, terminated by " - " */ | ||
| 508 | char *dash = strstr (blank + 1, " - "); | ||
| 509 | if (! dash) | ||
| 510 | continue; | ||
| 511 | |||
| 512 | /* advance past the " - " separator. */ | ||
| 513 | char *fstype = dash + 3; | ||
| 514 | blank = terminate_at_blank (fstype); | ||
| 515 | if (! blank) | ||
| 516 | continue; | ||
| 517 | |||
| 518 | /* find end of SOURCE. */ | ||
| 519 | char *source = blank + 1; | ||
| 520 | if (! terminate_at_blank (source)) | ||
| 521 | continue; | ||
| 522 | |||
| 523 | /* manipulate the sub-strings in place. */ | ||
| 524 | unescape_tab (source); | ||
| 525 | unescape_tab (target); | ||
| 526 | unescape_tab (mntroot); | ||
| 527 | unescape_tab (fstype); | ||
| 528 | |||
| 529 | me = xmalloc (sizeof *me); | ||
| 530 | |||
| 531 | me->me_devname = xstrdup (source); | ||
| 532 | me->me_mountdir = xstrdup (target); | ||
| 533 | me->me_mntroot = xstrdup (mntroot); | ||
| 534 | me->me_type = xstrdup (fstype); | ||
| 535 | me->me_type_malloced = 1; | ||
| 536 | me->me_dev = makedev (devmaj, devmin); | ||
| 537 | /* we pass "false" for the "Bind" option as that's only | ||
| 538 | significant when the Fs_type is "none" which will not be | ||
| 539 | the case when parsing "/proc/self/mountinfo", and only | ||
| 540 | applies for static /etc/mtab files. */ | ||
| 541 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, false); | ||
| 542 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
| 543 | |||
| 544 | /* Add to the linked list. */ | ||
| 545 | *mtail = me; | ||
| 546 | mtail = &me->me_next; | ||
| 547 | } | ||
| 548 | |||
| 549 | free (line); | ||
| 550 | |||
| 551 | if (ferror (fp)) | ||
| 552 | { | ||
| 553 | int saved_errno = errno; | ||
| 554 | fclose (fp); | ||
| 555 | errno = saved_errno; | ||
| 556 | goto free_then_fail; | ||
| 557 | } | ||
| 558 | |||
| 559 | if (fclose (fp) == EOF) | ||
| 560 | goto free_then_fail; | ||
| 453 | } | 561 | } |
| 562 | else /* fallback to /proc/self/mounts (/etc/mtab). */ | ||
| 563 | # endif /* __linux __ || __ANDROID__ */ | ||
| 564 | { | ||
| 565 | struct mntent *mnt; | ||
| 566 | char const *table = MOUNTED; | ||
| 454 | 567 | ||
| 455 | if (endmntent (fp) == 0) | 568 | fp = setmntent (table, "r"); |
| 456 | goto free_then_fail; | 569 | if (fp == NULL) |
| 570 | return NULL; | ||
| 571 | |||
| 572 | while ((mnt = getmntent (fp))) | ||
| 573 | { | ||
| 574 | bool bind = hasmntopt (mnt, "bind"); | ||
| 575 | |||
| 576 | me = xmalloc (sizeof *me); | ||
| 577 | me->me_devname = xstrdup (mnt->mnt_fsname); | ||
| 578 | me->me_mountdir = xstrdup (mnt->mnt_dir); | ||
| 579 | me->me_mntroot = NULL; | ||
| 580 | me->me_type = xstrdup (mnt->mnt_type); | ||
| 581 | me->me_type_malloced = 1; | ||
| 582 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, bind); | ||
| 583 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
| 584 | me->me_dev = dev_from_mount_options (mnt->mnt_opts); | ||
| 585 | |||
| 586 | /* Add to the linked list. */ | ||
| 587 | *mtail = me; | ||
| 588 | mtail = &me->me_next; | ||
| 589 | } | ||
| 590 | |||
| 591 | if (endmntent (fp) == 0) | ||
| 592 | goto free_then_fail; | ||
| 593 | } | ||
| 457 | } | 594 | } |
| 458 | #endif /* MOUNTED_GETMNTENT1. */ | 595 | #endif /* MOUNTED_GETMNTENT1. */ |
| 459 | 596 | ||
| 460 | #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ | 597 | #ifdef MOUNTED_GETMNTINFO /* Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD */ |
| 461 | { | 598 | { |
| 462 | struct statfs *fsp; | 599 | struct statfs *fsp; |
| 463 | int entries; | 600 | int entries; |
| @@ -472,6 +609,7 @@ read_file_system_list (bool need_fs_type) | |||
| 472 | me = xmalloc (sizeof *me); | 609 | me = xmalloc (sizeof *me); |
| 473 | me->me_devname = xstrdup (fsp->f_mntfromname); | 610 | me->me_devname = xstrdup (fsp->f_mntfromname); |
| 474 | me->me_mountdir = xstrdup (fsp->f_mntonname); | 611 | me->me_mountdir = xstrdup (fsp->f_mntonname); |
| 612 | me->me_mntroot = NULL; | ||
| 475 | me->me_type = fs_type; | 613 | me->me_type = fs_type; |
| 476 | me->me_type_malloced = 0; | 614 | me->me_type_malloced = 0; |
| 477 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | 615 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); |
| @@ -485,7 +623,7 @@ read_file_system_list (bool need_fs_type) | |||
| 485 | } | 623 | } |
| 486 | #endif /* MOUNTED_GETMNTINFO */ | 624 | #endif /* MOUNTED_GETMNTINFO */ |
| 487 | 625 | ||
| 488 | #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ | 626 | #ifdef MOUNTED_GETMNTINFO2 /* NetBSD, Minix */ |
| 489 | { | 627 | { |
| 490 | struct statvfs *fsp; | 628 | struct statvfs *fsp; |
| 491 | int entries; | 629 | int entries; |
| @@ -498,6 +636,7 @@ read_file_system_list (bool need_fs_type) | |||
| 498 | me = xmalloc (sizeof *me); | 636 | me = xmalloc (sizeof *me); |
| 499 | me->me_devname = xstrdup (fsp->f_mntfromname); | 637 | me->me_devname = xstrdup (fsp->f_mntfromname); |
| 500 | me->me_mountdir = xstrdup (fsp->f_mntonname); | 638 | me->me_mountdir = xstrdup (fsp->f_mntonname); |
| 639 | me->me_mntroot = NULL; | ||
| 501 | me->me_type = xstrdup (fsp->f_fstypename); | 640 | me->me_type = xstrdup (fsp->f_fstypename); |
| 502 | me->me_type_malloced = 1; | 641 | me->me_type_malloced = 1; |
| 503 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | 642 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); |
| @@ -511,35 +650,7 @@ read_file_system_list (bool need_fs_type) | |||
| 511 | } | 650 | } |
| 512 | #endif /* MOUNTED_GETMNTINFO2 */ | 651 | #endif /* MOUNTED_GETMNTINFO2 */ |
| 513 | 652 | ||
| 514 | #ifdef MOUNTED_GETMNT /* Ultrix. */ | 653 | #if defined MOUNTED_FS_STAT_DEV /* Haiku, also (obsolete) BeOS */ |
| 515 | { | ||
| 516 | int offset = 0; | ||
| 517 | int val; | ||
| 518 | struct fs_data fsd; | ||
| 519 | |||
| 520 | while (errno = 0, | ||
| 521 | 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, | ||
| 522 | (char *) 0))) | ||
| 523 | { | ||
| 524 | me = xmalloc (sizeof *me); | ||
| 525 | me->me_devname = xstrdup (fsd.fd_req.devname); | ||
| 526 | me->me_mountdir = xstrdup (fsd.fd_req.path); | ||
| 527 | me->me_type = gt_names[fsd.fd_req.fstype]; | ||
| 528 | me->me_type_malloced = 0; | ||
| 529 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | ||
| 530 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
| 531 | me->me_dev = fsd.fd_req.dev; | ||
| 532 | |||
| 533 | /* Add to the linked list. */ | ||
| 534 | *mtail = me; | ||
| 535 | mtail = &me->me_next; | ||
| 536 | } | ||
| 537 | if (val < 0) | ||
| 538 | goto free_then_fail; | ||
| 539 | } | ||
| 540 | #endif /* MOUNTED_GETMNT. */ | ||
| 541 | |||
| 542 | #if defined MOUNTED_FS_STAT_DEV /* BeOS */ | ||
| 543 | { | 654 | { |
| 544 | /* The next_dev() and fs_stat_dev() system calls give the list of | 655 | /* The next_dev() and fs_stat_dev() system calls give the list of |
| 545 | all file systems, including the information returned by statvfs() | 656 | all file systems, including the information returned by statvfs() |
| @@ -622,6 +733,7 @@ read_file_system_list (bool need_fs_type) | |||
| 622 | me->me_devname = xstrdup (fi.device_name[0] != '\0' | 733 | me->me_devname = xstrdup (fi.device_name[0] != '\0' |
| 623 | ? fi.device_name : fi.fsh_name); | 734 | ? fi.device_name : fi.fsh_name); |
| 624 | me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name); | 735 | me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name); |
| 736 | me->me_mntroot = NULL; | ||
| 625 | me->me_type = xstrdup (fi.fsh_name); | 737 | me->me_type = xstrdup (fi.fsh_name); |
| 626 | me->me_type_malloced = 1; | 738 | me->me_type_malloced = 1; |
| 627 | me->me_dev = fi.dev; | 739 | me->me_dev = fi.dev; |
| @@ -644,7 +756,7 @@ read_file_system_list (bool need_fs_type) | |||
| 644 | } | 756 | } |
| 645 | #endif /* MOUNTED_FS_STAT_DEV */ | 757 | #endif /* MOUNTED_FS_STAT_DEV */ |
| 646 | 758 | ||
| 647 | #if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */ | 759 | #if defined MOUNTED_GETFSSTAT /* OSF/1, also (obsolete) Apple Darwin 1.3 */ |
| 648 | { | 760 | { |
| 649 | int numsys, counter; | 761 | int numsys, counter; |
| 650 | size_t bufsize; | 762 | size_t bufsize; |
| @@ -671,6 +783,7 @@ read_file_system_list (bool need_fs_type) | |||
| 671 | me = xmalloc (sizeof *me); | 783 | me = xmalloc (sizeof *me); |
| 672 | me->me_devname = xstrdup (stats[counter].f_mntfromname); | 784 | me->me_devname = xstrdup (stats[counter].f_mntfromname); |
| 673 | me->me_mountdir = xstrdup (stats[counter].f_mntonname); | 785 | me->me_mountdir = xstrdup (stats[counter].f_mntonname); |
| 786 | me->me_mntroot = NULL; | ||
| 674 | me->me_type = xstrdup (FS_TYPE (stats[counter])); | 787 | me->me_type = xstrdup (FS_TYPE (stats[counter])); |
| 675 | me->me_type_malloced = 1; | 788 | me->me_type_malloced = 1; |
| 676 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | 789 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); |
| @@ -686,31 +799,25 @@ read_file_system_list (bool need_fs_type) | |||
| 686 | } | 799 | } |
| 687 | #endif /* MOUNTED_GETFSSTAT */ | 800 | #endif /* MOUNTED_GETFSSTAT */ |
| 688 | 801 | ||
| 689 | #if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */ | 802 | #if defined MOUNTED_FREAD_FSTYP /* (obsolete) SVR3 */ |
| 690 | { | 803 | { |
| 691 | struct mnttab mnt; | 804 | struct mnttab mnt; |
| 692 | char *table = "/etc/mnttab"; | 805 | char *table = "/etc/mnttab"; |
| 693 | FILE *fp; | 806 | FILE *fp; |
| 694 | 807 | ||
| 695 | fp = fopen (table, "r"); | 808 | fp = fopen (table, "re"); |
| 696 | if (fp == NULL) | 809 | if (fp == NULL) |
| 697 | return NULL; | 810 | return NULL; |
| 698 | 811 | ||
| 699 | while (fread (&mnt, sizeof mnt, 1, fp) > 0) | 812 | while (fread (&mnt, sizeof mnt, 1, fp) > 0) |
| 700 | { | 813 | { |
| 701 | me = xmalloc (sizeof *me); | 814 | me = xmalloc (sizeof *me); |
| 702 | # ifdef GETFSTYP /* SVR3. */ | ||
| 703 | me->me_devname = xstrdup (mnt.mt_dev); | 815 | me->me_devname = xstrdup (mnt.mt_dev); |
| 704 | # else | ||
| 705 | me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); | ||
| 706 | strcpy (me->me_devname, "/dev/"); | ||
| 707 | strcpy (me->me_devname + 5, mnt.mt_dev); | ||
| 708 | # endif | ||
| 709 | me->me_mountdir = xstrdup (mnt.mt_filsys); | 816 | me->me_mountdir = xstrdup (mnt.mt_filsys); |
| 817 | me->me_mntroot = NULL; | ||
| 710 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | 818 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ |
| 711 | me->me_type = ""; | 819 | me->me_type = ""; |
| 712 | me->me_type_malloced = 0; | 820 | me->me_type_malloced = 0; |
| 713 | # ifdef GETFSTYP /* SVR3. */ | ||
| 714 | if (need_fs_type) | 821 | if (need_fs_type) |
| 715 | { | 822 | { |
| 716 | struct statfs fsd; | 823 | struct statfs fsd; |
| @@ -723,7 +830,6 @@ read_file_system_list (bool need_fs_type) | |||
| 723 | me->me_type_malloced = 1; | 830 | me->me_type_malloced = 1; |
| 724 | } | 831 | } |
| 725 | } | 832 | } |
| 726 | # endif | ||
| 727 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | 833 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); |
| 728 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | 834 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); |
| 729 | 835 | ||
| @@ -744,34 +850,57 @@ read_file_system_list (bool need_fs_type) | |||
| 744 | if (fclose (fp) == EOF) | 850 | if (fclose (fp) == EOF) |
| 745 | goto free_then_fail; | 851 | goto free_then_fail; |
| 746 | } | 852 | } |
| 747 | #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ | 853 | #endif /* MOUNTED_FREAD_FSTYP. */ |
| 748 | 854 | ||
| 749 | #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ | 855 | #ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */ |
| 750 | { | 856 | { |
| 751 | struct mntent **mnttbl = getmnttbl (), **ent; | 857 | struct extmnttab mnt; |
| 752 | for (ent = mnttbl; *ent; ent++) | 858 | const char *table = MNTTAB; |
| 859 | FILE *fp; | ||
| 860 | int ret; | ||
| 861 | |||
| 862 | /* No locking is needed, because the contents of /etc/mnttab is generated | ||
| 863 | by the kernel. */ | ||
| 864 | |||
| 865 | errno = 0; | ||
| 866 | fp = fopen (table, "re"); | ||
| 867 | if (fp == NULL) | ||
| 868 | ret = errno; | ||
| 869 | else | ||
| 753 | { | 870 | { |
| 754 | me = xmalloc (sizeof *me); | 871 | while ((ret = getextmntent (fp, &mnt, 1)) == 0) |
| 755 | me->me_devname = xstrdup ((*ent)->mt_resource); | 872 | { |
| 756 | me->me_mountdir = xstrdup ((*ent)->mt_directory); | 873 | me = xmalloc (sizeof *me); |
| 757 | me->me_type = xstrdup ((*ent)->mt_fstype); | 874 | me->me_devname = xstrdup (mnt.mnt_special); |
| 758 | me->me_type_malloced = 1; | 875 | me->me_mountdir = xstrdup (mnt.mnt_mountp); |
| 759 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | 876 | me->me_mntroot = NULL; |
| 760 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | 877 | me->me_type = xstrdup (mnt.mnt_fstype); |
| 761 | me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ | 878 | me->me_type_malloced = 1; |
| 879 | me->me_dummy = MNT_IGNORE (&mnt) != 0; | ||
| 880 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | ||
| 881 | me->me_dev = makedev (mnt.mnt_major, mnt.mnt_minor); | ||
| 762 | 882 | ||
| 763 | /* Add to the linked list. */ | 883 | /* Add to the linked list. */ |
| 764 | *mtail = me; | 884 | *mtail = me; |
| 765 | mtail = &me->me_next; | 885 | mtail = &me->me_next; |
| 886 | } | ||
| 887 | |||
| 888 | ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; | ||
| 889 | /* Here ret = -1 means success, ret >= 0 means failure. */ | ||
| 890 | } | ||
| 891 | |||
| 892 | if (0 <= ret) | ||
| 893 | { | ||
| 894 | errno = ret; | ||
| 895 | goto free_then_fail; | ||
| 766 | } | 896 | } |
| 767 | endmnttbl (); | ||
| 768 | } | 897 | } |
| 769 | #endif | 898 | #endif /* MOUNTED_GETEXTMNTENT */ |
| 770 | 899 | ||
| 771 | #ifdef MOUNTED_GETMNTENT2 /* SVR4. */ | 900 | #ifdef MOUNTED_GETMNTENT2 /* Solaris < 8, also (obsolete) SVR4 */ |
| 772 | { | 901 | { |
| 773 | struct mnttab mnt; | 902 | struct mnttab mnt; |
| 774 | char *table = MNTTAB; | 903 | const char *table = MNTTAB; |
| 775 | FILE *fp; | 904 | FILE *fp; |
| 776 | int ret; | 905 | int ret; |
| 777 | int lockfd = -1; | 906 | int lockfd = -1; |
| @@ -784,7 +913,7 @@ read_file_system_list (bool need_fs_type) | |||
| 784 | # ifndef MNTTAB_LOCK | 913 | # ifndef MNTTAB_LOCK |
| 785 | # define MNTTAB_LOCK "/etc/.mnttab.lock" | 914 | # define MNTTAB_LOCK "/etc/.mnttab.lock" |
| 786 | # endif | 915 | # endif |
| 787 | lockfd = open (MNTTAB_LOCK, O_RDONLY); | 916 | lockfd = open (MNTTAB_LOCK, O_RDONLY | O_CLOEXEC); |
| 788 | if (0 <= lockfd) | 917 | if (0 <= lockfd) |
| 789 | { | 918 | { |
| 790 | struct flock flock; | 919 | struct flock flock; |
| @@ -806,7 +935,7 @@ read_file_system_list (bool need_fs_type) | |||
| 806 | # endif | 935 | # endif |
| 807 | 936 | ||
| 808 | errno = 0; | 937 | errno = 0; |
| 809 | fp = fopen (table, "r"); | 938 | fp = fopen (table, "re"); |
| 810 | if (fp == NULL) | 939 | if (fp == NULL) |
| 811 | ret = errno; | 940 | ret = errno; |
| 812 | else | 941 | else |
| @@ -816,6 +945,7 @@ read_file_system_list (bool need_fs_type) | |||
| 816 | me = xmalloc (sizeof *me); | 945 | me = xmalloc (sizeof *me); |
| 817 | me->me_devname = xstrdup (mnt.mnt_special); | 946 | me->me_devname = xstrdup (mnt.mnt_special); |
| 818 | me->me_mountdir = xstrdup (mnt.mnt_mountp); | 947 | me->me_mountdir = xstrdup (mnt.mnt_mountp); |
| 948 | me->me_mntroot = NULL; | ||
| 819 | me->me_type = xstrdup (mnt.mnt_fstype); | 949 | me->me_type = xstrdup (mnt.mnt_fstype); |
| 820 | me->me_type_malloced = 1; | 950 | me->me_type_malloced = 1; |
| 821 | me->me_dummy = MNT_IGNORE (&mnt) != 0; | 951 | me->me_dummy = MNT_IGNORE (&mnt) != 0; |
| @@ -828,6 +958,7 @@ read_file_system_list (bool need_fs_type) | |||
| 828 | } | 958 | } |
| 829 | 959 | ||
| 830 | ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; | 960 | ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; |
| 961 | /* Here ret = -1 means success, ret >= 0 means failure. */ | ||
| 831 | } | 962 | } |
| 832 | 963 | ||
| 833 | if (0 <= lockfd && close (lockfd) != 0) | 964 | if (0 <= lockfd && close (lockfd) != 0) |
| @@ -841,26 +972,26 @@ read_file_system_list (bool need_fs_type) | |||
| 841 | } | 972 | } |
| 842 | #endif /* MOUNTED_GETMNTENT2. */ | 973 | #endif /* MOUNTED_GETMNTENT2. */ |
| 843 | 974 | ||
| 844 | #ifdef MOUNTED_VMOUNT /* AIX. */ | 975 | #ifdef MOUNTED_VMOUNT /* AIX */ |
| 845 | { | 976 | { |
| 846 | int bufsize; | 977 | int bufsize; |
| 847 | char *entries, *thisent; | 978 | void *entries; |
| 979 | char *thisent; | ||
| 848 | struct vmount *vmp; | 980 | struct vmount *vmp; |
| 849 | int n_entries; | 981 | int n_entries; |
| 850 | int i; | 982 | int i; |
| 851 | 983 | ||
| 852 | /* Ask how many bytes to allocate for the mounted file system info. */ | 984 | /* Ask how many bytes to allocate for the mounted file system info. */ |
| 853 | if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0) | 985 | entries = &bufsize; |
| 986 | if (mntctl (MCTL_QUERY, sizeof bufsize, entries) != 0) | ||
| 854 | return NULL; | 987 | return NULL; |
| 855 | entries = xmalloc (bufsize); | 988 | entries = xmalloc (bufsize); |
| 856 | 989 | ||
| 857 | /* Get the list of mounted file systems. */ | 990 | /* Get the list of mounted file systems. */ |
| 858 | n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); | 991 | n_entries = mntctl (MCTL_QUERY, bufsize, entries); |
| 859 | if (n_entries < 0) | 992 | if (n_entries < 0) |
| 860 | { | 993 | { |
| 861 | int saved_errno = errno; | ||
| 862 | free (entries); | 994 | free (entries); |
| 863 | errno = saved_errno; | ||
| 864 | return NULL; | 995 | return NULL; |
| 865 | } | 996 | } |
| 866 | 997 | ||
| @@ -892,6 +1023,7 @@ read_file_system_list (bool need_fs_type) | |||
| 892 | vmp->vmt_data[VMT_OBJECT].vmt_off); | 1023 | vmp->vmt_data[VMT_OBJECT].vmt_off); |
| 893 | } | 1024 | } |
| 894 | me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); | 1025 | me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); |
| 1026 | me->me_mntroot = NULL; | ||
| 895 | me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); | 1027 | me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); |
| 896 | me->me_type_malloced = 1; | 1028 | me->me_type_malloced = 1; |
| 897 | options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; | 1029 | options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; |
| @@ -910,7 +1042,7 @@ read_file_system_list (bool need_fs_type) | |||
| 910 | } | 1042 | } |
| 911 | #endif /* MOUNTED_VMOUNT. */ | 1043 | #endif /* MOUNTED_VMOUNT. */ |
| 912 | 1044 | ||
| 913 | #ifdef MOUNTED_INTERIX_STATVFS | 1045 | #ifdef MOUNTED_INTERIX_STATVFS /* Interix */ |
| 914 | { | 1046 | { |
| 915 | DIR *dirp = opendir ("/dev/fs"); | 1047 | DIR *dirp = opendir ("/dev/fs"); |
| 916 | char node[9 + NAME_MAX]; | 1048 | char node[9 + NAME_MAX]; |
| @@ -924,6 +1056,8 @@ read_file_system_list (bool need_fs_type) | |||
| 924 | struct dirent entry; | 1056 | struct dirent entry; |
| 925 | struct dirent *result; | 1057 | struct dirent *result; |
| 926 | 1058 | ||
| 1059 | /* FIXME: readdir_r is planned to be withdrawn from POSIX and | ||
| 1060 | marked obsolescent in glibc. Use readdir instead. */ | ||
| 927 | if (readdir_r (dirp, &entry, &result) || result == NULL) | 1061 | if (readdir_r (dirp, &entry, &result) || result == NULL) |
| 928 | break; | 1062 | break; |
| 929 | 1063 | ||
| @@ -935,6 +1069,7 @@ read_file_system_list (bool need_fs_type) | |||
| 935 | me = xmalloc (sizeof *me); | 1069 | me = xmalloc (sizeof *me); |
| 936 | me->me_devname = xstrdup (dev.f_mntfromname); | 1070 | me->me_devname = xstrdup (dev.f_mntfromname); |
| 937 | me->me_mountdir = xstrdup (dev.f_mntonname); | 1071 | me->me_mountdir = xstrdup (dev.f_mntonname); |
| 1072 | me->me_mntroot = NULL; | ||
| 938 | me->me_type = xstrdup (dev.f_fstypename); | 1073 | me->me_type = xstrdup (dev.f_fstypename); |
| 939 | me->me_type_malloced = 1; | 1074 | me->me_type_malloced = 1; |
| 940 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); | 1075 | me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); |
| @@ -946,6 +1081,7 @@ read_file_system_list (bool need_fs_type) | |||
| 946 | mtail = &me->me_next; | 1081 | mtail = &me->me_next; |
| 947 | } | 1082 | } |
| 948 | } | 1083 | } |
| 1084 | closedir (dirp); | ||
| 949 | } | 1085 | } |
| 950 | #endif /* MOUNTED_INTERIX_STATVFS */ | 1086 | #endif /* MOUNTED_INTERIX_STATVFS */ |
| 951 | 1087 | ||
| @@ -953,7 +1089,7 @@ read_file_system_list (bool need_fs_type) | |||
| 953 | return mount_list; | 1089 | return mount_list; |
| 954 | 1090 | ||
| 955 | 1091 | ||
| 956 | free_then_fail: | 1092 | free_then_fail: _GL_UNUSED_LABEL; |
| 957 | { | 1093 | { |
| 958 | int saved_errno = errno; | 1094 | int saved_errno = errno; |
| 959 | *mtail = NULL; | 1095 | *mtail = NULL; |
| @@ -972,10 +1108,12 @@ read_file_system_list (bool need_fs_type) | |||
| 972 | 1108 | ||
| 973 | /* Free a mount entry as returned from read_file_system_list (). */ | 1109 | /* Free a mount entry as returned from read_file_system_list (). */ |
| 974 | 1110 | ||
| 975 | void free_mount_entry (struct mount_entry *me) | 1111 | void |
| 1112 | free_mount_entry (struct mount_entry *me) | ||
| 976 | { | 1113 | { |
| 977 | free (me->me_devname); | 1114 | free (me->me_devname); |
| 978 | free (me->me_mountdir); | 1115 | free (me->me_mountdir); |
| 1116 | free (me->me_mntroot); | ||
| 979 | if (me->me_type_malloced) | 1117 | if (me->me_type_malloced) |
| 980 | free (me->me_type); | 1118 | free (me->me_type); |
| 981 | free (me); | 1119 | free (me); |
