diff options
Diffstat (limited to 'libc/misc/statfs/internal_statvfs.c')
-rw-r--r-- | libc/misc/statfs/internal_statvfs.c | 112 |
1 files changed, 57 insertions, 55 deletions
diff --git a/libc/misc/statfs/internal_statvfs.c b/libc/misc/statfs/internal_statvfs.c index 29890d490..717673921 100644 --- a/libc/misc/statfs/internal_statvfs.c +++ b/libc/misc/statfs/internal_statvfs.c @@ -16,6 +16,9 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +/* The kernel hints us if the f_flags is valid */ +#define ST_VALID 0x0020 + /* Now fill in the fields we have information for. */ buf->f_bsize = fsbuf.f_bsize; #ifdef _STATFS_F_FRSIZE @@ -31,7 +34,7 @@ buf->f_ffree = fsbuf.f_ffree; if (sizeof (buf->f_fsid) == sizeof (fsbuf.f_fsid)) buf->f_fsid = (fsbuf.f_fsid.__val[0] - | ((unsigned long int) fsbuf.f_fsid.__val[1] + | ((unsigned long long int) fsbuf.f_fsid.__val[1] << (8 * (sizeof (buf->f_fsid) - sizeof (fsbuf.f_fsid.__val[0]))))); else @@ -43,9 +46,6 @@ #endif buf->f_namemax = fsbuf.f_namelen; memset (buf->__f_spare, '\0', sizeof(fsbuf.f_spare)); - - /* What remains to do is to fill the fields f_favail and f_flag. */ - /* XXX I have no idea how to compute f_favail. Any idea??? */ buf->f_favail = buf->f_ffree; @@ -54,61 +54,63 @@ file. The way we can test for matching filesystem is using the device number. */ buf->f_flag = 0; - if (STAT (&st) >= 0) - { - int save_errno = errno; - struct mntent mntbuf; - FILE *mtab; - - mtab = setmntent ("/proc/mounts", "r"); - if (mtab == NULL) - mtab = setmntent (_PATH_MOUNTED, "r"); + if (STAT (&st) >= 0 +#ifdef _STATFS_F_FLAGS + && (fsbuf.f_flags & ST_VALID) == 0 +#endif + ) { + int save_errno = errno; + struct mntent mntbuf; + FILE *mtab; - if (mtab != NULL) - { - char tmpbuf[1024]; + mtab = setmntent ("/proc/mounts", "r"); + if (mtab == NULL) + mtab = setmntent (_PATH_MOUNTED, "r"); + if (mtab != NULL) { + char tmpbuf[1024]; - while (getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) - { - struct stat fsst; + while (getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) { + struct stat fsst; - /* Find out about the device the current entry is for. */ - if (stat (mntbuf.mnt_dir, &fsst) >= 0 - && st.st_dev == fsst.st_dev) - { - /* Bingo, we found the entry for the device FD is on. - Now interpret the option string. */ - char *cp = mntbuf.mnt_opts; - char *opt; + /* Find out about the device the current entry is for. */ + if (stat (mntbuf.mnt_dir, &fsst) >= 0 + && st.st_dev == fsst.st_dev) { + /* Bingo, we found the entry for the device FD is on. + Now interpret the option string. */ + char *cp = mntbuf.mnt_opts; + char *opt; - while ((opt = strsep (&cp, ",")) != NULL) - if (strcmp (opt, "ro") == 0) - buf->f_flag |= ST_RDONLY; - else if (strcmp (opt, "nosuid") == 0) - buf->f_flag |= ST_NOSUID; + while ((opt = strsep (&cp, ",")) != NULL) + if (strcmp (opt, "ro") == 0) + buf->f_flag |= ST_RDONLY; + else if (strcmp (opt, "nosuid") == 0) + buf->f_flag |= ST_NOSUID; #ifdef __USE_GNU - else if (strcmp (opt, "noexec") == 0) - buf->f_flag |= ST_NOEXEC; - else if (strcmp (opt, "nodev") == 0) - buf->f_flag |= ST_NODEV; - else if (strcmp (opt, "sync") == 0) - buf->f_flag |= ST_SYNCHRONOUS; - else if (strcmp (opt, "mand") == 0) - buf->f_flag |= ST_MANDLOCK; - else if (strcmp (opt, "noatime") == 0) - buf->f_flag |= ST_NOATIME; - else if (strcmp (opt, "nodiratime") == 0) - buf->f_flag |= ST_NODIRATIME; + else if (strcmp (opt, "noexec") == 0) + buf->f_flag |= ST_NOEXEC; + else if (strcmp (opt, "nodev") == 0) + buf->f_flag |= ST_NODEV; + else if (strcmp (opt, "sync") == 0) + buf->f_flag |= ST_SYNCHRONOUS; + else if (strcmp (opt, "mand") == 0) + buf->f_flag |= ST_MANDLOCK; + else if (strcmp (opt, "noatime") == 0) + buf->f_flag |= ST_NOATIME; + else if (strcmp (opt, "nodiratime") == 0) + buf->f_flag |= ST_NODIRATIME; + else if (strcmp (opt, "relatime") == 0) + buf->f_flag |= ST_RELATIME; #endif - - /* We can stop looking for more entries. */ - break; + /* We can stop looking for more entries. */ + break; + } } - } - - /* Close the file. */ - endmntent (mtab); - } - - __set_errno (save_errno); - } + /* Close the file. */ + endmntent (mtab); + } + __set_errno (save_errno); + } +#ifdef _STATFS_F_FLAGS + else + buf->f_flag = fsbuf.f_flags ^ ST_VALID; +#endif |