为什么dirent.h不能在sshfs驱动器上运行?

时间:2018-01-02 03:45:35

标签: c++ sshfs dirent.h

这是我用来测试它的代码。 它适用于普通目录,但不适用于在sshfs下安装的目录。 我的目标是使用这些方法 https://github.com/jlettvin/Greased-Grep 旨在允许全局模糊搜索 必须存在的关键字和必须缺席的关键字。

#include <iostream>
#include <string>
#include <functional>
#include <dirent.h>

using std::cout;
using std::endl;
using std::string;
using std::function;

bool neither (const char* path)
{
        bool ret = (path != nullptr);
        if (ret)
        {
                if (path[0] == '.')
                {
                        if (path[1] == '\0') ret = false;
                        if (path[1] == '.' && path[2] == '\0') ret = false;
                }
        }
        return ret;
}

void walk (const string &path, function<void (const string &)> talk)
{
    if (auto dir = opendir (path.c_str ())) {
        while (auto f = readdir (dir)) {
                        auto name = f->d_name;
                        auto type = f->d_type;
                        if (neither (name))
                        {
                                switch (type)
                                {
                                        case DT_DIR: walk (path + name + "/", talk); break;
                                        case DT_REG: talk (path + name            ); break;
                                }
                        }
        }
        closedir(dir);
    }
}

int main (int argc, char** argv)
{
        walk ("./", [](const string &path) { cout << path << endl; });
        return 0;
}

2 个答案:

答案 0 :(得分:2)

您需要review the following documentation in the Linux's readdir(3) manual page

  unsigned char       d_type;     /* Type of file; not supported
                                by all filesystem types */

具体来说,您的注意力集中在&#34;所有文件系统类型都不支持&#34;一部分。

您的代码需要设置d_type。但是,readdir(3)并不保证会出现这种情况。

d_type的一个可能值是:

DT_UNKNOWN

    The file type could not be determined.

应准备好处理所有可能性的代码必须明确检查DT_UNKNOWN,如果是,则将d_name附加到目录名称stat()文件名,然后抓住文件类型从那里。

d_type是一种捷径。如果它设置好了。你马上就可以了。如果没有,你必须努力去做。

sshfs显然不支持从d_type返回readdir(3)。希望sshfs实现stat()

P.S。,除了目录和常规文件之外,还有其他一些特殊类型,您可能需要或不必处理(假设sshfs甚至可以提供给您)。这是你需要自己调查的东西。

答案 1 :(得分:0)

我有我想要操作的代码。

经过对各种旗帜,条件和情况的各种敏感性的大量试验,我决定完全简单。

我将一切都视为目录和文件。如果它不是目录,我会检测并忽略所有错误并继续。如果它是一个目录,那么我打开它并搜索其内容以寻找我想要的内容。这是Greased-Grep的一个优势,其目标是找到匹配模式的东西。文件名就像它们的内容一样。

所以,我的答案是,我不关心失败。我只关心成功,所以我在没有任何测试的情况下解雇失败。

当降序sshfs挂载目录时,这可以正常工作。

任何对此代码看起来如何感兴趣的人都可以关注我的github: https://github.com/jlettvin/Greased-Grep/blob/master/gg.cpp

以下是显着的代码:

void walk (const string& a_path)
{
    // Don't attempt to assess validity of filenames... just fail.
    // Treat directories like files and search filenames in directories.
    // This enables gg to work on sshfs mounted filesystems.
    auto d{a_path};
    auto s{d.size ()};
    if (s && d[s - 1] == '/') d.resize (s-1);
    errno = 0;
    if (auto dir = opendir (d.c_str ()))
    {
        while (!errno)
        {
            if (auto f = readdir (dir))
            {
                if (auto p = f->d_name)
                {
                    if (auto q = p)
                    {
                        if (!(*q++ == '.' && (!*q || (*q++ == '.' && !*q))))
                        {
                            auto e = d + "/" + p;
                            walk (e);
                            mapped_search (e.c_str ());
                            errno = 0;
                        }
                    }
                    else break;
                }
                else break;
            }
            else break;
        }
    }
}