1

I am trying to do a file be deleted when a program ends. I remember that before I could put the unlink() before the first close() and I don't need reopen the file.

What I expect: The file is erased after the program ends.

What is happening: The file is erased when the call to unlink happens the file is erased.

My sample program:

int main()
{
    int fd = open(argv[1], O_CREAT);
    int x = 1;
    write(fd, "1234\n", 5);
    close(fd);

    fd = open(argv[1], 0);
    unlink(argv[1]);

    while (x <= 3)
    {
      int k;
      scanf(" %d", &k);

      x++;
    }

    close(fd);
    return 0;
}

Has a way that I can open() the file, interact with it and on close() delete the file from harddisk? I'm using fedora linux 18.

I need know the name of the file that I did open in this way because it will be used by another application.

Ricardo Lucca
  • 158
  • 3
  • 10
  • 2
    `it is not working now` Can you describe how? Does something happen differently than you expect? Do you get an error? – ajp15243 Jan 19 '15 at 16:07
  • Why would you open the file delete it and then close it? Isn't it open the file close it and then delete it the right thing to do? – Iharob Al Asimi Jan 19 '15 at 16:09
  • 1
    @iharob this to have some more guarantee that nobody will try to modify the file while he is working with it... – Jean-Baptiste Yunès Jan 19 '15 at 16:10
  • 1
    It works well in my case (OSX), and I can't see why it doesn't work on your platform. Describe your problem with more details... – Jean-Baptiste Yunès Jan 19 '15 at 16:12
  • well there exists [`flock();`](http://unixhelp.ed.ac.uk/CGI/man-cgi?flock+2) – Iharob Al Asimi Jan 19 '15 at 16:13
  • This is not the same! `flock` will advisory lock the (existing) file, while in his case the file is externally inexistent and internally used. – Jean-Baptiste Yunès Jan 19 '15 at 16:15
  • @ajp15243, what I expected is that the file that I deleted stay in disk during the life time of the program. – Ricardo Lucca Jan 19 '15 at 16:47
  • @RicardoLucca You still haven't described what happens instead, which is crucial for anyone here to help you. Based on what you've told us, we only know that it's "not working", and nothing else. The more details you give, the better. Edit it all into your question with the `edit` link at the bottom of your question. – ajp15243 Jan 19 '15 at 17:00
  • http://stackoverflow.com/questions/2028874/what-happens-to-an-open-file-handler-on-linux-if-the-pointed-file-gets-moved-de i think the behavior is kind of expected. if you remove/unlink an open file, it get removed from other process' view but continue available to you. how do you measure "erased"? – Dyno Fu Jan 19 '15 at 17:40

3 Answers3

2

Unlinking a file simply detaches the file name from the underlying inode, making it impossible to open the file using that file name afterwards.

If any process has the file still open, they can happily read and write it, as those operations operate on the inode and not the file name. Also, if there are hardlinks (other file names referring to the same inode) left, those other file names can be used to open the file just fine. See e.g. the Wikipedia article on inodes for further details.


Edited to add:

In Linux, you can leverage the /proc pseudofilesystem. If your application (with process ID PID) has file descriptor FD open, with the file name already unlinked, it can still let another application work on it by telling the other application to work on /proc/PID/fd/FD. It is a pseudo-file, meaning it looks like a (non-functioning!) symlink, but it is not -- it's just useful Linux kernel magic: as long as the other application just opens it normally (open()/fopen() etc., no lstat()/readlink() stuff), they will get access as if they were opening a normal file.

As a real-world example, open two terminals, and in one write

bash -c 'exec 3<>foobar ; echo $$ ; rm foobar ; echo "Initial contents" >&3 ; cat >&3'

The first line it outputs is the PID, and FD is 3 here. Anything you type (after pressing Enter) will be appended to a file that was briefly named foobar, but no longer exists. (You can easily verify that.)

In a second terminal, type

cat /proc/PID/fd/3

to see what that file contains.

Nominal Animal
  • 38,216
  • 5
  • 59
  • 86
  • yes, but I am considering wrong the fact that the file vanish before I did the close. If it vanish another program cant open it without know the inode. – Ricardo Lucca Jan 19 '15 at 17:55
  • @RicardoLucca: Tell the other process to use `/proc/PID/fd/FD`, where `PID` is the original process pid, and `FD` is the file descriptor in the original process. See my edited answer for details. – Nominal Animal Jan 19 '15 at 18:15
1

It sounds like what you really want is tmpfile():

The tmpfile() function opens a unique temporary file in binary read/write (w+b) mode. The file will be automatically deleted when it is closed or the program terminates.

FoggyDay
  • 11,962
  • 4
  • 34
  • 48
0

The File is unlinked, so it won't show up from ls... but the file still exists there is an inode and you could actually re-link it... the file won't be removed from the disk until all file descriptors pointing to it are closed...

you could still read and write to the fd while it is open after it is unlinked...

Grady Player
  • 14,399
  • 2
  • 48
  • 76