c++ - 安全使用 std::tmpnam

标签 c++ c++11 stl

所以我正在开发一个应用程序,它需要创建一个文件,写入其中,调用另一个程序以该文件作为输入,然后删除该文件。

我寻找可能的解决方案,一个解决方案如下所示。

std::FILE* tmpf = std::tmpfile();
std::fputs("Hello, world", tmpf);

根据 std::tmpfile 的文档,如果文件被手动关闭,或者程序以自然方式退出,文件将被删除。这看起来是个不错的解决方案,但有一个异常(exception)。它看起来很乱(使用 C I/O,而不是 C++ 流)。

另一种解决方案是使用 std::tmpnam , 这将生成唯一的文件名。

std::string file_name = std::tmpname(NULL);
// (*)
std::fstream stream{file_name};
stream << "Hello World" << std::endl;

但是这个也有问题。如果另一个程序创建同名文件,而我的程序在 (*) 中,我们将对同一个文件进行操作,这当然是我想避免的事情。

C++ STL(仍然)不支持文件系统操作,比如检查文件是否存在。我可以使用类似 stat 的东西检查,但由于检查文件和创建它不是原子的,它不会解决任何问题。而且我没有找到C++ STL原子操作的方法,它会:检查文件是否存在,如果不存在,打开它,如果是,则失败。

那么,我的问题是,解决这个问题的正确方法是什么?我错过了什么吗?

最佳答案

您的规范“...创建一个文件,写入其中,以该文件作为输入调用另一个程序,然后删除该文件。”与 tmpfile() 不兼容。一方面,没有(可移植的)方法从从 tmpfile() 获取的 FILE 指针获取文件名,其次在 POSIX 平台上,tmpfile() 通常会在从 tmpfile() 返回之前从目录中删除文件(如果您不熟悉 POSIX 文件系统语义,只要您的进程有一个打开的文件描述符,该文件就存在,即使它已从目录中删除,这意味着无法从文件系统访问它。

鉴于此,您将不得不使用某种 tmpname() 类型的方法,并找出一种方法来防止两个进程同时访问它(文件锁、使用 stat() 检查链接计数等)。

或者更好的是,不要使用文件进行进程间通信。对于最简单的(?)情况,在父级中创建一个管道,将其连接到子级的标准输入。

关于c++ - 安全使用 std::tmpnam,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33935862/

相关文章:

c++ - 用 C++ 表示离散傅里叶变换的复数

c++ - 类对象的参数没有改变

c++ - 从函数调用推导模板参数包

c++ - 如何使用STL解决这个问题?

c++ - 警告 : 'auto' type specifier is a C++11 extension

c++ - 使用 boost strand 和 std::mutex

c++ - 仿函数和对象继承

c++ - 多线程环境中的静态局部变量初始化

c++ - 如何将事件监听器/信号添加到简单的超人类?

c++ - 在 C++ 中分配元素地址时出错