一尘不染

文件挂载在哪里?

linux

给定文件或目录的路径,如何确定该文件的安装点?例如,如果/tmp作为tmpfs文件系统挂载,则给定文件名,/tmp/foo/bar我想知道它存储在tmpfs根目录下/tmp

这将是C ++语言,我希望避免通过调用外部命令system()。该代码应该健壮-不一定要防止故意的篡改,但绝对要面对嵌套的安装点,符号链接等。

我还没有找到一个简单的系统调用来执行此操作。看来我得自己写支票。这是我计划的粗略概述。

  1. readlinkshell命令中规范化文件名。 怎么样?
  2. /etc/mtabgetmntent()&合作阅读。
  3. 确定文件的相应安装项。 怎么样?

对于#1,有一个简单的系统调用,还是我需要读取路径的每个目录组件,并用readlink(2)符号链接来解析它们?和处理...自己?似乎很痛苦。

对于#3,我对如何执行此操作有各种想法。不知道哪个最好。

  1. open()文件,其父级,其父级的父级等,openat(fd, "..")直到到达其中一项为止/etc/mtab。( 我怎么知道什么时候?fstat()它们并比较inode的数量?
  2. 在安装表中找到最长的目录名称,它是我文件名的子字符串。

我倾向于第一种选择,但是在编写全部代码之前,我想确保我没有忽略任何东西-理想情况是内置函数已经做到了!


阅读 490

收藏
2020-06-07

共1个答案

一尘不染

这就是我想出的。原来,通常不需要遍历父目录。您所要做的就是获取文件的设备号,然后找到具有相同设备号的相应安装条目。

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编号。

2020-06-07