I'd like to know in my C/Fortran code if the working directory is local to the host or actually remotely mounted e.g. NFS disks? Wanting to do this on both Windows and Linux.
-
1It is not a feature of the programming languages, but a feature of the operating system. You can run a shell command to do so, which depends on the OS. – gdlmx Jan 10 '20 at 18:48
-
@EugeneSh. [POSIX provides `[f]statvfs()`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html). Comparing the file system ID of the initial directory to the file system ID of all mounted file systems should work. And the Linux-specific `statfs()` call directly provides a file system type, which may be sufficient. – Andrew Henle Jan 10 '20 at 20:50
-
@AndrewHenle You can mount NFS as well. Will this be detected? Upd: yeah, `statfs` seems to be good. – Eugene Sh. Jan 10 '20 at 20:52
-
For Linux, you can simply read `/proc/mounts` and scan for the beginning of the current directory to determine where the directory is mounted. Simply `cat /proc/mounts` in a terminal to examine the file. – David C. Rankin Jan 10 '20 at 20:54
-
@EugeneSh. [`statfs()`](http://man7.org/linux/man-pages/man2/statfs.2.html) provides `f_type`, of which `NFS_SUPER_MAGIC` might be sufficient. I haven't tested that thoroughly, though. – Andrew Henle Jan 10 '20 at 20:55
-
@DavidC.Rankin *For Linux, you can simply read `/proc/mounts` ...* Note that only works with the canonical path of the original directory. – Andrew Henle Jan 10 '20 at 20:57
-
Yes, correct, it's not a solution for everything, but if you are concerned about NFS or CIFS, FUSE, etc.. it is a quick hack. – David C. Rankin Jan 10 '20 at 21:10
-
will give a try. thanks for inputs. – boreas Jan 10 '20 at 23:38
2 Answers
In C on Windows, you are probably looking for the Windows API function GetDriveType. To find the current working directory, you can use the function GetCurrentDirectory. However, according to the documentation, it is sufficient to simply call
GetDriveType( NULL );
if you want to inspect the drive of the current working directory.
I don't know what the equivalent functions for Fortran and Linux are.

- 22,760
- 4
- 24
- 39
Linux solution
First, you need to find the file system the directory is mounted on.
Unless you want to go through path parsing, you can use the file system ID from the statfs()
call:
SYNOPSIS
#include <sys/vfs.h> /* or <sys/statfs.h> */ int statfs(const char *path, struct statfs *buf); int fstatfs(int fd, struct statfs *buf);
DESCRIPTION
The
statfs()
system call returns information about a mounted filesystem.path
is the pathname of any file within the mounted filesystem.buf
is a pointer to a statfs structure defined approximately as follows:struct statfs { __fsword_t f_type; /* Type of filesystem (see below) */ __fsword_t f_bsize; /* Optimal transfer block size */ fsblkcnt_t f_blocks; /* Total data blocks in filesystem */ fsblkcnt_t f_bfree; /* Free blocks in filesystem */ fsblkcnt_t f_bavail; /* Free blocks available to unprivileged user */ fsfilcnt_t f_files; /* Total file nodes in filesystem */ fsfilcnt_t f_ffree; /* Free file nodes in filesystem */ fsid_t f_fsid; /* Filesystem ID */ __fsword_t f_namelen; /* Maximum length of filenames */ __fsword_t f_frsize; /* Fragment size (since Linux 2.6) */ __fsword_t f_flags; /* Mount flags of filesystem (since Linux 2.6.36) */ __fsword_t f_spare[xxx]; /* Padding bytes reserved for future use */ };
The following filesystem types may appear in
f_type
:...
This may be sufficient for your purposes - the data in f_type
might be sufficient to inform you that the file is on local or remote disks (As long as you're ignoring the potential to NFS-mount a local file system exported from the local machine, among other issues noted below.)
For a more portable solution, you can use the POSIX-standardized available-on-Linux statvfs()
call for the file system ID given a path:
SYNOPSIS
#include <sys/statvfs.h> int statvfs(const char *path, struct statvfs *buf); int fstatvfs(int fd, struct statvfs *buf);
DESCRIPTION
The function
statvfs()
returns information about a mounted filesystem. path is the pathname of any file within the mounted filesystem. buf is a pointer to astatvfs
structure defined approximately as follows:struct statvfs { unsigned long f_bsize; /* Filesystem block size */ unsigned long f_frsize; /* Fragment size */ fsblkcnt_t f_blocks; /* Size of fs in f_frsize units */ fsblkcnt_t f_bfree; /* Number of free blocks */ fsblkcnt_t f_bavail; /* Number of free blocks for unprivileged users */ fsfilcnt_t f_files; /* Number of inodes */ fsfilcnt_t f_ffree; /* Number of free inodes */ fsfilcnt_t f_favail; /* Number of free inodes for unprivileged users */ unsigned long f_fsid; /* Filesystem ID */ unsigned long f_flag; /* Mount flags */ unsigned long f_namemax; /* Maximum filename length */ };
Once you get the f_fsid
value for your directory, you need to find the mount point for that filesystem.
Linux provides getmntent()
et al for this purpose:
SYNOPSIS
#include <stdio.h> #include <mntent.h> FILE *setmntent(const char *filename, const char *type); struct mntent *getmntent(FILE *stream); int addmntent(FILE *stream, const struct mntent *mnt); int endmntent(FILE *streamp); char *hasmntopt(const struct mntent *mnt, const char *opt); /* GNU extension */ #include <mntent.h> struct mntent *getmntent_r(FILE *streamp, struct mntent *mntbuf, char *buf, int buflen);
Feature Test Macro Requirements for glibc (see
feature_test_macros(7)
):getmntent_r(): Since glibc 2.19: _DEFAULT_SOURCE Glibc 2.19 and earlier: _BSD_SOURCE || _SVID_SOURCE
DESCRIPTION
These routines are used to access the filesystem description file
/etc/fstab
and the mounted filesystem description file/etc/mtab
.The
setmntent()
function opens the filesystem description file filename and returns a file pointer which can be used bygetmntent()
. The argument type is the type of access required and can take the same values as the mode argument offopen(3)
. The returned stream should be closed usingendmntent()
rather thanfclose(3)
.The
getmntent()
function reads the next line of the filesystem description file from stream and returns a pointer to a structure containing the broken out fields from a line in the file. The pointer points to a static area of memory which is overwritten by subsequent calls togetmntent()
.The
addmntent()
function adds themntent
structuremnt
to the end of the open stream.The
endmntent()
function closes the stream associated with the filesystem description file.The
hasmntopt()
function scans the mnt_opts field (see below) of themntent
structure mnt for a substring that matches opt. See<mntent.h>
andmount(8)
for valid mount options.The reentrant
getmntent_r()
function is similar togetmntent()
, but stores thestruct mount
in the provided*mntbuf
and stores the strings pointed to by the entries in that struct in the provided arraybuf
of sizebuflen
.The mntent structure is defined in <mntent.h> as follows:
struct mntent { char *mnt_fsname; /* name of mounted filesystem */ char *mnt_dir; /* filesystem path prefix */ char *mnt_type; /* mount type (see mntent.h) */ char *mnt_opts; /* mount options (see mntent.h) */ int mnt_freq; /* dump frequency in days */ int mnt_passno; /* pass number on parallel fsck */ };
See Linux function to get mount points for some code examples.
In your case, you would call statfs()
or statvfs()
on the path held in the mnt_dir
field of the struct mntent
and get the filesystem ID of that filesystem, and when it matched the filesystem ID from your directory, you'd have the mount point - and all the details for the filesystem.
You could also parse file paths and find the longest mnt_dir
in the mounted filesystems returned from getmntent()
that matches the canonical path of your directory. But in that case you need to handle softlinks crossing filesystem boundaries. And I'm not sure if hard links to directories are still strictly prohibited - if not, using path names can never be definitive.
Note regarding loopback devices
A loopback device is a way to mount a file as a filesystem. You'll have to decide if you treat a file or directory mounted on a loopback device as a local file, or if you trace it back to the actual file being used as the loopback file system and use that to determine if your original directory is local or remote.
Note about bind
mounts
Linux provides the capability to do bind
mounts, where a directory can be "mounted" at another location. This is another case where you have to decide if you need to trace back through the mounts to determine if your original directory is local or remote.

- 18,769
- 10
- 104
- 133

- 32,625
- 3
- 24
- 56