Search code examples
clinuxmacosposixstdio

How to check if a path specifies a volume root directory


How can I check whether a given path (absolute or relative) specifies the root directory of a volume with POSIX or standard C runtime calls? Ideally, the code should work on both, Linux and Mac OS X.


Solution

  • First, all you can really check using standard functions is if the path presented is a mount point, and that mount point may or may not be the root of its filesystem.

    Assuming your system assigns a unique f_fsid value to each mount point, you can use the POSIX-stanard statvfs() function and compare the f_fsid field of the relevant statvfs structure of the path component with its parent:

    #include <stdlib.h>
    #include <string.h>
    #include <sys/statvfs.h>
    
    
    int isMountPoint( const char *path )
    {
        struct statvfs sv1, sv2;
    
        char *realP = realpath( path, NULL );
    
        // if the real path is "/", yeah, it's the root
        if ( !strcmp( realP, "/" ) )
        {
            free( realP );
            return( 1 );
        }
    
        statvfs( realP, &sv1 );
    
        // find the parent by truncating at the last "/"
        char *pp = strrchr( realP, '/' );
    
        // if there is no parent, must be root
        if ( NULL == pp )
        {
            free( realP );
            return( 1 );
        }
    
        // keep the final / (makes handling things like "/mnt"
        // much easier)
        pp++;
        *pp = '\0';
    
        statvfs( realP, &sv2 );
        free( realP );
    
        // if f_fsid differs, it's the root of
        // the mounted filesystem
        return( sv1.f_fsid != sv2.f_fsid );
    }
    

    All error checking is left as an exercise (and it would also make this example longer and harder to understand...).

    If the f_fsid of a path differs from its parent's f_fsid, or if the path is the root directory itself, the path passed in must be the mount point of its filesystem. Note that this does not have to be the actual root of the filesystem. For example, a host can export a file system via NFS, and an NFS client can mount any subdirectory in the remote file system as the "local root", or a loopback mount can refer to a subdirectory of another filesystem.