给定文件或目录的路径,如何确定该文件的安装点?例如,如果/tmp
作为tmpfs
文件系统挂载,那么给定文件名/tmp/foo/bar
我想知道它存储在以tmpfs
root为中/tmp
.
这将是在C++中,我想避免通过调用外部命令system()
.代码应该是健壮的 - 不一定是针对故意篡改,但绝对面对嵌套的挂载点,符号链接等.
我无法找到一个简单的系统调用来执行此操作.看起来我必须自己写支票.这是我正在计划的大致轮廓.
readlink
shell命令.怎么样?/etc/mtab
与getmntent()
&CO.对于#1是一个简单的系统调用还是我需要读取路径的每个目录组件并解决它们,readlink(2)
如果它们是符号链接?处理.
和..
我自己?好像很痛苦.
对于#3,我对如何做到这一点有各种各样的想法.不确定哪个最好.
open()
文件,其父级,父级的父级等使用,openat(fd, "..")
直到我到达其中一个/etc/mtab
条目.(我怎么知道我什么时候做?fstat()
并比较inode数字?)我倾向于第一个选项,但在我编码之前,我想确保我不会忽略任何东西 - 理想情况下,内置函数已经完成了!
Joh*_*ica 18
这就是我想出来的.事实证明,通常不需要遍历父目录.您所要做的就是获取文件的设备编号,然后找到具有相同设备编号的相应安装条目.
struct mntent *mountpoint(char *filename, struct mntent *mnt, char *buf, size_t buflen)
{
struct stat s;
FILE * fp;
dev_t dev;
if (stat(filename, &s) != 0) {
return NULL;
}
dev = s.st_dev;
if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
return NULL;
}
while (getmntent_r(fp, mnt, buf, buflen)) {
if (stat(mnt->mnt_dir, &s) != 0) {
continue;
}
if (s.st_dev == dev) {
endmntent(fp);
return mnt;
}
}
endmntent(fp);
// Should never reach here.
errno = EINVAL;
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
感谢@RichardPennington提出的建议realpath()
,以及比较设备编号而不是inode编号.