Sometimes while designing a software, you might have a requirement to hold some data (for reprocessing at later stage) for some duration. Some software do it within the memory in which they are running while others may create a temporary file for this purpose.
Creating temporary files to hold data is a popular practice among the software developers. There exist several system calls that are used for creating temporary files. Now one would think that why would we require system calls to create temporary files. Well the major reason behind this is to have unique temporary file names. Suppose there is a program that creates a temporary file while running and suppose multiple instances of same program are running simultaneously. If the uniqueness of temporary files is not kept in mind then multiple instances of same program may try to create temporary files with same name leading to conflict.
Now one may argue that uniqueness can be maintained by checking whether a file with same name exists or not. Agreed!!!! But this would result in a bulky code being added to the software logic to perform this operation successfully. So, its nice if the system provides some calls that can do this stuff for your software.
There are many system calls available to manipulate temporary files :
- mkstemp()
- tmpfile()
- tempnam()
- tmpnam()
- unlink()
While mkstemp, tmpfile, tempnam and tmpnam functions are used for creating a temporary file, the unlink function is used for removing a created temporary file. Here in this article, we will focus on the mkstemp() and unlink() system calls.
The mkstemp() and unlink() system calls
The signature of mkstemp() looks like :
#include <stdlib.h> int mkstemp(char *template);
This system calls creates and opens the temporary file and returns the open file descriptor for it. The argument ‘template’ is used to generate the temporary file name. Since ‘template’ literally acts like a template name so the last six characters of the buffer passed as ‘template’ must contain “XXXXXX” as these characters are replaced by the system call to make the temporary file name unique.
The signature of unlink() looks like :
#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.
Also, to understand how to manipulate a directory within C program, refer to C Programming with Directories.
An Example
Lets have a look at an example where we use the mkstemp() and unlink() calls to demonstrate their usage for manipulating temporary files.
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<errno.h> int main(void) { // buffer to hold the temporary file name char nameBuff[32]; // buffer to hold data to be written/read to/from temporary file char buffer[24]; int filedes = -1,count=0; // memset the buffers to 0 memset(nameBuff,0,sizeof(nameBuff)); memset(buffer,0,sizeof(buffer)); // Copy the relevant information in the buffers strncpy(nameBuff,"/tmp/myTmpFile-XXXXXX",21); strncpy(buffer,"Hello World",11); errno = 0; // Create the temporary file, this function will replace the 'X's filedes = mkstemp(nameBuff); // Call unlink so that whenever the file is closed or the program exits // the temporary file is deleted unlink(nameBuff); if(filedes<1) { printf("\n Creation of temp file failed with error [%s]\n",strerror(errno)); return 1; } else { printf("\n Temporary file [%s] created\n", nameBuff); } errno = 0; // Write some data to the temporary file if(-1 == write(filedes,buffer,sizeof(buffer))) { printf("\n write failed with error [%s]\n",strerror(errno)); return 1; } printf("\n Data written to temporary file is [%s]\n",buffer); // reset the buffer as it will be used in read operation now memset(buffer,0,sizeof(buffer)); errno = 0; // rewind the stream pointer to the start of temporary file if(-1 == lseek(filedes,0,SEEK_SET)) { printf("\n lseek failed with error [%s]\n",strerror(errno)); return 1; } errno=0; // read the data from temporary file if( (count =read(filedes,buffer,11)) < 11 ) { printf("\n read failed with error [%s]\n",strerror(errno)); return 1; } // Show whatever is read printf("\n Data read back from temporary file is [%s]\n",buffer); return 0; }
In the example above :
- Created and open temporary file using the mkstemp() function.
- This function updates the Xs in the name we used with some characters that make the overall name unique.
- Just after the creation, the function unlink() was called.
- Calling unlink() does not delete the file immediately but waits for the file to get closed or the process to exit.
- Through the write function some data is written to the temporary file
- Through the read function the data is read back.
- The above two operations show that the temporary file can be used as any other normal file to perform file operations.
- As soon as the process exits, the file is deleted by unlink().
The output of the above program is :
# ./tempfile Temporary file [/tmp/myTmpFile-wH5sLq] created Data written to temporary file is [Hello World] Data read back from temporary file is [Hello World]
So we see that the Xs that we used in temporary file name template were actually replaced by the some random characters (wH5sLq in this case) making the temporary file name unique.
Comments on this entry are closed.
Hi,
Thanks a lot for very nice article
Hi,
I have a confusion between using “bash scripting” and using “C programming in Linux”
Can you explain when to use which?
Thanks
Thanks very much, really good article!
mkstemp, tmpfile, tempnam and tmpnam are not system calls. They are implemented inside libc.
unlink is a system call however user space programs should call remove() instead.
Alex.
Hi, thanks for a wonderful article.
Is there any particular reason why you use memset+strncpy, instead of strcpy ?
I saw a similar thing in your previous tutorial on “C Programming with Directories”. Kindly help, if there is something deeper that I missing. 🙂
Thanks
What a different of all functions?
I have a question. when I create a file and unlink it, then sleep 10s for that I have time for run `ls` command to show it, finally close file. But run `ls` not show the file
I just create when the program sleep.