Today, when we saw the implementation scheme of mutual exclusion using File locks in nginx, we found that FD is required after the unlink file, which is very confusing! So I searched this article and tested it myself. I got the rising posture ~ Share with you ~
Principle:
Each file can obtain the file information through a struct stat struct. One of the member st_nlink represents the number of links to the file.
When you use the shell touch command or open a non-existent file with o_creat in the program, the number of links to the file is 1.
Generally, opening an existing file does not affect the number of links of the file. The function of open is only to establish an access relationship between the calling process and the file, that is, the FD is returned after open. The Calling process can read, write, ftruncate, and perform a series of file operations through FD.
Close () is to eliminate the access relationship between the calling process and the file. Naturally, the number of links to the file is not affected. When close is called, the kernel checks the number of processes that open the file. If this number is 0, the kernel further checks the number of links to the file. If this number is also 0, the file content will be deleted.
The link function creates a new directory item and adds a number of links.
The unlink function deletes directory items and reduces the number of links. If the number of links reaches 0 and no process opens the file, the file content will be deleted. If the file is not closed before unlilnk, the file content can still be accessed.
To sum up, the operations that really affect the number of links are link, unlink, and open creation.
The true meaning of deleting a file is that the number of links to the file is 0, and the essence of this operation is Unlink.
Close can delete the file content, because there is an unlink operation before close.
Verification:
# Include <stdio. h> # include <sys/types. h> # include <sys/STAT. h> # include <fcntl. h> # include <unistd. h> int main () {int FD; char Buf [32]; struct stat Buff; struct stat buff2; If (FD = open ("temp.txt ", o_rdwr | o_creat | o_trunc, s_irwxu) <0) {printf ("Create File error! \ N ");} Stat (" temp.txt ", & buff); printf (" temp. link = % d \ n ", Buff. st_nlink); Link ("temp.txt", "test.txt"); Stat ("test.txt", & buff); printf ("after link the TEM. link = % d \ n ", Buff. st_nlink); If (unlink ("test.txt") <0) {printf ("unlink error! \ N ");} Stat (" temp.txt ", & buff); printf (" after unlink TEM. link = % d \ n ", Buff. st_nlink); If (unlink ("temp.txt") <0) {printf ("unlink error! \ N ");}
// Here we use the fstat function instead of the stat function, because unlilnk has deleted the file name, so it cannot be accessed through the file name.
// However, FD is still open and the file content has not been deleted. You can still use FD to obtain the file information fstat (FD, & buff); printf ("after unlink TEM. link = % u \ n ", Buff. st_nlink); If (write (FD, "Temp", 5) <0) {printf ("Write wrror! \ N ");} If (lseek (FD, 0, seek_set) =-1) {printf (" lseek error! \ N ");} If (read (FD, Buf, 5) <0) {printf (" read error! \ N ");} printf (" % s \ n ", Buf); Return 0 ;}
Unlink and close relationships