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 30f4286..6d38481 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); |