Delete a file using Linux unlink function

By | 10/09/2012

Sometimes it is required to delete a file present on disk from within the C code. In Linux this can be done through the Linux unlink function. This function holds the capability to delete the file but under certain conditions.

Linux unlink function

Here is an excerpt from the man page :

#include <unistd.h>
int unlink(const char *pathname);

unlink() deletes a name from the file system. If that name was the last link to a file and no processes have the file open the file is deleted and the space it was using is made available for reuse.

If the name was the last link to a file but any processes still have the file open the file will remain in existence until the last file descriptor referring to it is closed.

If the name referred to a symbolic link the link is removed.

If the name referred to a socket, fifo or device the name for it is removed but processes which have the object open may continue to use it.

So the above text makes its clear that the unlink() function can delete the file provided that there are no more links present to the file and no process has the file open. In case multiple links are present then this function just decrements the link count and returns.

A basic example

Here is a basic example :

#include<stdio.h>

#include<string.h>

#include<errno.h>

#include<unistd.h>

int main(void)
{
    errno = 0;

    if(unlink("file_to_delete.txt"))
    {
        printf("\n unlink() failed - [%s]\n",strerror(errno));
    }
    else
    {
        printf("\n File deleted successfully\n");
    }

    return 0;
}

So we see that the code above is a basic code that uses the function ‘unlink()’ to delete the file ‘file_to_delete.txt’.

Lets first check the file :

$ ls file_to_delete.txt 
file_to_delete.txt

So we see that the file exists.

Now, lets compile and run the code :

$ gcc -Wall unlink.c -o unlink
$ ./unlink 

 File deleted successfully

So upon execution, the code claims that it deleted the file. Lets check again in the directory :

$ ls file_to_delete.txt 
ls: cannot access file_to_delete.txt: No such file or directory

So we see that the file is actually deleted from the disk.

What if the file is already open?

Well, suppose the file that is to be deleted is already open by some process. For example, open the file with a text editor and then execute the code above.

Here is the output :

First I opened the file with Linux text editor gedit.

$ gedit file_to_delete.txt

Next, I executed the code :

$ ./unlink 

 File deleted successfully

So the unlink() function still returned successfully. This means the file should have been deleted. I checked the editor and found that the file was still open there but from the directory, the name of the file was deleted.

$ ls file*
file  file1.c  file1.o  file1.txt  file2.c  file2.h  file2.o  file2.txt  file.c  fileHandling  fileHandling.c  fileHole  fileHole.c

So we see that the file name ‘file_to_delete.txt’ was no longer present in the directory.

But once I saved the file (which was already open in the editor) through editor (ctrl+s). The file name reappeared in the directory :

$ ls file*
file  file1.c  file1.o  file1.txt  file2.c  file2.h  file2.o  file2.txt  file.c  fileHandling  fileHandling.c  fileHole  fileHole.c  file_to_delete.txt

Also, without doing a ctrl+s, If I close the editor then in that case the file gets completely deleted from the disk. This is because the link count to the file becomes zero and the only process that is using the file has closed it.

Unlink cannot delete directories

Deleting a directory through unlink() function is not possible.

I tried to delete the directory ‘dir_to_delete’ and got the following output :

$ ./unlink 

 unlink() failed - [Is a directory]

So we see that unlink() clearly says that the entity being deleted is a directory.

Leave a Reply

Your email address will not be published. Required fields are marked *