Maxthecat Maxthecat - 21 days ago 5
C Question

How can I determine the mount path of a given file on Linux in C?

I have an arbitrary file for which I would like to determine the mount point. Let's say that it is /mnt/bar/foo.txt, where we have the following mount points in addition to the "normal" Linux mount points:

[some device mounted to] -> /mnt/bar
[some device mounted to] -> /mnt/other

I've taken a look at stat() and statvfs(). statvfs() can give me the filesystem id, and stat can give me the id of the device, but neither of these can really correlate to the mount point.

I'm thinking that what I will have to do is call readlink() on the arbitrary file, and then read through /proc/mounts, figuring out which path most closely matches the filename. Is this a good approach, or is there some great libc function I'm missing out on to to this?

Answer

You can do it with a combination of getfsent to iterate through the list of devices, and stat to check if your file is on that device.

#include <fstab.h>    /* for getfsent() */
#include <sys/stat.h> /* for stat() */

struct fstab *getfssearch(const char *path) {
    /* stat the file in question */
    struct stat path_stat;
    stat(path, &path_stat);

    /* iterate through the list of devices */
    struct fstab *fs = NULL;
    while( (fs = getfsent()) ) {
        /* stat the mount point */
        struct stat dev_stat;
        stat(fs->fs_file, &dev_stat);

        /* check if our file and the mount point are on the same device */
        if( dev_stat.st_dev == path_stat.st_dev ) {
            break;
        }
    }

    return fs;
}

Note, for brevity there's no error checking there. Also getfsent is not a POSIX function, but it is a very widely used convention. It works here on OS X which doesn't even use /etc/fstab. It is also not thread safe.