$ man tmpfile
说
标准没有指定tmpfile()将使用的目录。 Glibc将尝试
<stdio.h>
中定义的路径前缀P_tmpdir,如果 目录/ tmp失败。
我正在使用Ubuntu 13.10 x86_64,gcc和libc BTW。
因此,当我尝试使用tmpfile()创建临时文件时,我无法在/ tmp中看到任何临时文件。 (我在stdio.h中可以看到# define P_tmpdir "/tmp"
)。这是我使用的代码段:
#include <stdio.h>
int main(int argc, char **argv)
{
FILE *tmp;
tmp = tmpfile(); // Where's this file?
scanf("%*d");
return 0;
}
$ ./tmpfile
现在,当scanf正在等待下一个(冗余)输入时,我应该能够在/ tmp中看到一个临时文件。但我不能。那么这个tmpfile到底在哪里创建?
答案 0 :(得分:7)
可能直接删除目录中的文件条目。在POSIX系统上,只要您有一个打开的文件描述符,文件本身在删除后仍然有效。 (在您的情况下隐藏在FILE*
返回值中。)
使用这种技术,没有人可以潜入并打开该文件,只能通过变量tmp
访问它。
答案 1 :(得分:4)
编译代码并通过strace
运行代码会显示文件的位置和名称:
$ ./a.out
execve("./main", ["./main"], [/* 31 vars */]) = 0
brk(0) = 0xe0c000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f038c51a000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=103425, ...}) = 0
mmap(NULL, 103425, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f038c500000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\357\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1603600, ...}) = 0
mmap(NULL, 3717176, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f038bf71000
mprotect(0x7f038c0f3000, 2097152, PROT_NONE) = 0
mmap(0x7f038c2f3000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x182000) = 0x7f038c2f3000
mmap(0x7f038c2f8000, 18488, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f038c2f8000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f038c4ff000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f038c4fe000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f038c4fd000
arch_prctl(ARCH_SET_FS, 0x7f038c4fe700) = 0
mprotect(0x7f038c2f3000, 16384, PROT_READ) = 0
mprotect(0x7f038c51c000, 4096, PROT_READ) = 0
munmap(0x7f038c500000, 103425) = 0
stat("/tmp", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
getpid() = 25957
open("/tmp/tmpfflAlKG", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
unlink("/tmp/tmpfflAlKG") = 0
fcntl(3, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
brk(0) = 0xe0c000
brk(0xe2d000) = 0xe2d000
fstat(3, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f038c519000
lseek(3, 0, SEEK_CUR) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f038c518000
read(0, alk
"alk\n", 1024) = 4
exit_group(0) = ?
"/tmp/tmpfflAlKG"
通过open()
open("/tmp/tmpfflAlKG", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
然后立即获得unlink()
unlink("/tmp/tmpfflAlKG") = 0
所以可见目录条目消失了。
由于仍然对流程开放,文件本身对流程保持有效,直到流程close()
为止。后者通过调用exit_group()
:
exit_group(0) = ?
答案 2 :(得分:0)
来自https://en.cppreference.com/w/c/io/tmpfile:
在某些实现(例如Linux)上,此函数实际上创建,打开并立即从文件系统中删除文件:只要程序保留了已删除文件的打开文件描述符,该文件就存在,但是由于已将其删除,因此其名称不会出现在任何目录中,因此没有其他进程可以打开它。一旦文件描述符关闭,或者程序终止(正常或异常),文件系统将回收文件所占用的空间。
在某些实现方式(例如Windows)上,由于该功能可能会在系统目录中创建临时文件,因此需要提升的特权。