std::tmpfile() не выбирает местоположение TMPDIR

Я использую std::tmpfile() для создания временных файлов, но я хочу использовать расположение, отличное от /tmp. Я экспортирую $TMPDIR, чтобы указать новое местоположение, но std::tmpfile() не выбирает новое местоположение.

Как создать временные файлы с помощью std::tmpfile() в папке, отличной от /tmp?


person G Gill    schedule 09.07.2016    source источник
comment
Говорят, что реализация Linux фактически разъединяет файлы, так что их нельзя восстановить из-за пределов файловой системы /proc.   -  person Paul Stelian    schedule 09.07.2016
comment
Нигде не сказано, что tmpfile будет использовать такую ​​переменную окружения. На справочной странице Linux сказано, что Glibc попытается использовать префикс пути P_tmpdir определено в <stdio.h>, но это все.   -  person Some programmer dude    schedule 09.07.2016
comment
Как установить P_tmpdir местоположение? и решит ли это мою проблему?   -  person G Gill    schedule 09.07.2016
comment
Какую реальную проблему вы пытаетесь решить? Даже если вы сможете получить std::tmpfile() для хранения вашего файла в другом месте, вы все равно не сможете получить доступ, кроме как через возвращенный FILE *, поскольку реализация glibc немедленно удаляет файл, полагаясь на поддержку чтения и записи в ОС. удаленные файлы, пока у вас открыт дескриптор.   -  person    schedule 09.07.2016


Ответы (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;
}

и след

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
person kfsone    schedule 09.07.2016