给定文件或目录的路径,如何确定该文件的安装点?例如,如果/tmp作为tmpfs文件系统挂载,则给定文件名,/tmp/foo/bar我想知道它存储在tmpfs根目录下/tmp。
/tmp
tmpfs
/tmp/foo/bar
这将是C ++语言,我希望避免通过调用外部命令system()。该代码应该健壮-不一定要防止故意的篡改,但绝对要面对嵌套的安装点,符号链接等。
system()
我还没有找到一个简单的系统调用来执行此操作。看来我得自己写支票。这是我计划的粗略概述。
readlink
/etc/mtab
getmntent()
对于#1,有一个简单的系统调用,还是我需要读取路径的每个目录组件,并用readlink(2)符号链接来解析它们?和处理.与..自己?似乎很痛苦。
readlink(2)
.
..
对于#3,我对如何执行此操作有各种想法。不知道哪个最好。
open()
openat(fd, "..")
fstat()
我倾向于第一种选择,但是在编写全部代码之前,我想确保我没有忽略任何东西-理想情况是内置函数已经做到了!
这就是我想出的。原来,通常不需要遍历父目录。您所要做的就是获取文件的设备号,然后找到具有相同设备号的相应安装条目。
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; }
感谢@RichardPennington率先提出realpath()并比较设备编号而不是inode编号。
realpath()