Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

temporary file location when using tmpfile() in C

$ man tmpfile says

The standard does not specify the directory that tmpfile() will use. Glibc will try the path prefix P_tmpdir defined in <stdio.h>, and if that fails the directory /tmp.

I am using Ubuntu 13.10 x86_64, gcc and libc BTW.

So when I try to create temporary file using using tmpfile(), I can't see any temporary file in /tmp. ( I can see # define P_tmpdir "/tmp" in stdio.h). This is the code snippet I used:

#include <stdio.h>

int main(int argc, char **argv)
{
    FILE *tmp;

    tmp = tmpfile();                            // Where's this file?
    scanf("%*d");

    return 0;
}

$ ./tmpfile
Now while scanf is waiting for the next (redundant) input I should have been able to see a temporary file in /tmp. But I can't. So Where does exactly this tmpfile get created?

like image 280
rootkea Avatar asked Feb 19 '15 13:02

rootkea


People also ask

What is the function of file * Tmpfile void?

h> FILE * tmpfile ( void ); The tmpfile() function opens a temporary file for reading and writing, and returns the corresponding FILE pointer.

Which directory is used to store temporary files Linux?

The /tmp directory in Linux based systems contains necessary files that are temporarily required by the system as well as other software and applications running on the machine. For example, when you are writing a document, all the content inside that document is saved as a temporary file inside the /tmp directory.

What is temporary data file?

A temporary file is a file created to store information temporarily, either for a program's intermediate use or for transfer to a permanent file when complete.


2 Answers

Probably the file entry in the directory is deleted directly. On POSIX systems the file itself remains valid after deletion, as long as you have an open file descriptor to it. (In your case hidden in the FILE* return value.)

With that technique, nobody can sneak in and open that file, it is only accessible through your variable tmp.

like image 148
Jens Gustedt Avatar answered Sep 19 '22 14:09

Jens Gustedt


Compiling your code and running it through strace reveals the file's location and name:

$ ./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" gets created via open()

open("/tmp/tmpfflAlKG", O_RDWR|O_CREAT|O_EXCL, 0600) = 3

and then immediatly gets unlink()

unlink("/tmp/tmpfflAlKG")               = 0

so the visible directory entry disappears.

As still open to the process the file itself stays valid for the process until the process close()s it. The latter happens implicitly via the call to exit_group():

exit_group(0)                           = ?
like image 28
alk Avatar answered Sep 16 '22 14:09

alk