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
CodePudding user response:
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.