【问题标题】:std::tmpfile() not picking TMPDIR locationstd::tmpfile() 没有选择 TMPDIR 位置
【发布时间】:2016-07-09 17:30:32
【问题描述】:

我正在使用 std::tmpfile() 创建临时文件,但我想使用 /tmp 以外的位置。我正在导出 $TMPDIR 以指向新位置,但 std::tmpfile() 没有选择新位置。

如何在 /tmp 以外的文件夹中使用 std::tmpfile() 创建临时文件?

【问题讨论】:

  • 据说Linux实现实际上是取消了文件的链接,因此无法真正从/proc文件系统外部恢复
  • 没有地方说tmpfile 会使用这样的环境变量。 The Linux manual page 说“Glibc 将尝试在 <stdio.h> 中定义的路径前缀 P_tmpdir”,但仅此而已。
  • 如何设置P_tmpdir 位置?这能解决我的问题吗?
  • 您要解决的真正问题是什么?即使您能够让std::tmpfile() 将您的文件存储在其他位置,您仍然无法通过返回的FILE * 进行访问,因为glibc 的实现会立即删除该文件,依靠操作系统来支持读取只要您打开了句柄,就可以从和写入已删除的文件。

标签: c++ c++11 temporary-files tmp


【解决方案1】:

快速测试程序

#include <stdio.h>
#include <stdlib.h>
#include <cstdlib>
#include <iostream>

int main()
{
    const char* tf = std::tmpnam(nullptr);
    std::cout << "tmpfile: " << tf << '\n';
    return 0;
}

和一个 ltrace

osmith@osmith-VirtualBox:~$ ltrace ./test.exe
__libc_start_main(0x400836, 1, 0x7ffedf17e178, 0x4008e0 <unfinished ...>
_ZNSt8ios_base4InitC1Ev(0x601171, 0xffff, 0x7ffedf17e188, 160)                  = 0
__cxa_atexit(0x400700, 0x601171, 0x601058, 0x7ffedf17df50)                      = 0
tmpnam(0, 0x7ffedf17e178, 0x7ffedf17e188, 192)                                  = 0x7fe4db5a0700
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x601060, 0x400965, -136, 0x7fe4db2d13d5) = 0x601060
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x601060, 0x7fe4db5a0700, 0x601060, 0xfbad2a84) = 0x601060
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c(0x601060, 10, 0x7fe4db91d988, 0x57474f44696b656ctmpfile: /tmp/filekiDOGW
) = 0x601060
_ZNSt8ios_base4InitD1Ev(0x601171, 0, 0x400700, 0x7fe4db59fd10)                  = 0x7fe4db922880
+++ exited (status 0) +++

确认,根据手册页,std::tmpnam 没有参考环境变量,它只使用常量P_tmpdir

如果这纯粹是针对 Linux 的,您可以改用 mkstemp

#include <stdio.h>
#include <stdlib.h>
#include <cstdlib>
#include <iostream>
#include <unistd.h>

int main()
{
    char tmpl[] = "/var/tmp/testXXXXXX";
    int f = mkstemp(tmpl);
    if (f < 0) {
        std::cerr << "mkstemp failed\n";
        return 1;
    }
    std::cout << tmpl << '\n';
    close(f);
    return 0;
}

演示:

osmith@osmith-VirtualBox:~$ g++ -o test.exe test.cpp -std=c++14
osmith@osmith-VirtualBox:~$ ./test.exe
/var/tmp/testEFULD4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多