创建一个唯一的临时目录

时间:2018-10-21 07:22:31

标签: c++ c++17

我正在尝试在系统temp文件夹中创建一个唯一的临时目录,并且一直在阅读有关tmpnam()的安全性和文件创建问题的信息。

我写了下面的代码,想知道它是否可以满足这些问题,我对tmpnam()函数的使用是否正确以及是否抛出了filesystem_error?我是否应该添加其他检查(例如temp_directory_path,它也会引发异常)?

    // Unique temporary directory path in the system temporary directory path.
std::filesystem::path tmp_dir_path {std::filesystem::temp_directory_path() /= std::tmpnam(nullptr)};

// Attempt to create the directory.
if (std::filesystem::create_directories(tmp_dir_path)) {

    // Directory successfully created.
    return tmp_dir_path;

} else {

    // Directory could not be created.
    throw std::filesystem_error("directory could not be created.");

}

2 个答案:

答案 0 :(得分:5)

来自cppreference.com

  

尽管很难猜出std :: tmpnam生成的名称,但是在std :: tmpnam返回到程序尝试使用返回的名称之间,可能有另一个进程创建了具有该名称的文件。创建文件。

问题不在于您如何使用它,而在于您使用它的事实。

例如,在您的代码示例中,如果恶意用户成功猜测并在第一行和第二行之间创建了目录,则它可能会拒绝您应用程序中的服务(DOS),这可能很重要,或者不是很重要。 / p>

相反,有一种方法可以在不兼容POSIX的系统上进行比赛:

  • 有关文件,请参见mkstemp(3)以获取更多信息
  • 有关目录的更多信息,请参见mkdtemp(3)

答案 1 :(得分:1)

您的代码很好。由于您尝试创建目录,因此OS将在您的进程与尝试创建同一文件的另一个进程之间进行仲裁,因此,如果您获胜,您将拥有,如果您丢失,则会得到该文件错误。

我最近写了一个类似的函数。是否引发异常取决于您要如何使用此函数。例如,您可以简单地返回打开或关闭的std::fstream并使用std::fstream::is_open作为成功的度量标准,或者在失败时返回空的路径名。

如果您不提供std::error_code参数,则查找std::filesystem::create_directories时会抛出自己的异常,因此您无需抛出自己的异常:

std::filesystem::path tmp_dir_path {std::filesystem::temp_directory_path() /= std::tmpnam(nullptr)};

// Attempt to create the directory.
std::filesystem::create_directories(tmp_dir_path));

// If that failed an exception will have been thrown
// so no need to check or throw your own

// Directory successfully created.
return tmp_dir_path;