cposixstatblock-device

Find device file from the st_dev field in a file contained in the device


I want to access a device (opening it) with the only information about the device being an st_dev field in a file stat struct.

int fd;
char *path;
struct stat buf;
stat("/path/to/my/file", &buf);
// do some things with buf.st_dev
// then either path contains a path to the device refered by st_dev or fd contains a file descriptor refering to it.

I want to find a way to do this either in a POSIX portable way, or with distincts specific ways for at least Linux and MacOS systems


Solution

  • Direct interaction with a block device requires a device node. The device node controls permissions (who can access the device directly).

    Theoretical solution: call mknod or mknodat to create a block device (S_IFBLK) with the given dev_t value. It needs to be on a filesystem that supports device files.

    mknod("/var/run/myprogram/mydevice", S_IFBLK | S_IRUSR | S_IWUSR, buf.st_dev);
    

    This requires elevated privileges: classically root permissions. On Linux, the CAP_MKNOD capability is sufficient, but some security frameworks may prevent even root from creating device nodes in random places. I don't know whether this requires more than root permissions on macOS.

    Make sure not to give unprivileged programs access to the device.

    Practical solution: look under /dev for a suitable device, i.e. a block device ((found_stat.st_mode & S_IFBLK) != 0) such that found_stat.st_rdev == buf.st_dev. There's no POSIX C function that does the recursive search, so you'll have to code it manually.

    While find can do the recursive traversal, it has no option to match a device file by its device number, which makes it inconvenient to locate the desired device.