Somewhere online I've seen a technique to immediately unlink a temporary file after opening it, since you will discard it anyway. As per my understanding of the man-page for unlink, the file will not be unlinked as long as it has an open file descriptor.
When I execute the following piece of code:
char *file, *command;
asprintf(&file, "/tmp/tempXXXXXX");
int fd = mkstemp(file);
unlink(file);
asprintf(&command, "some_command > %s", file); /*Writes n bytes in temp file*/
FILE *f = popen(command, "re");
pclose(f);
struct stat sbuf;
fstat(fd, &sbuf);
printf("%i\n", sbuf.st_size);
close(fd);
free(file);
free(command);
exit(0);
It will print a size of 0. However, if I comment unlink(file), it will show the correct file size. I would expect both scenarios to show the correct size of the file, since unlink should wait till no processes have the file open anymore. What am I missing here?
You're missing the fact that the file referred to by your fd is not the same file as that created by your call to
popen().In a POSIX-like shell,
some_command > some_filewill createsome_fileif it does not already exist, otherwise it will truncatesome_file.Your call to popen() invokes a shell, which in turn creates or truncates the output file before invoking
some_commandas per POSIX.Since you have unlinked
some_filebefore the call to popen(), the file is created anew: that is, the output file set up by yourpopen()shell is allocated under a different inode than the (now anonymous) file created by your previous call tomkstemp().You can see that the files are different if you compare
st_inovalues from yourfstat()(by fd) and a separate call tostat()(by name) after thepopen().