Abstract:This article mainly discusses the basic application of the fcntl function for file control. the DUP function can copy file descriptors, while the fcntl function is similar to the DUP function. in addition, it provides more powerful functions to obtain or set the nature of opened files and operate on file locks.
1. fcntl Function
In DUP and dup2, DUP and dup2 functions are introduced, which provide the function of copying an existing file descriptor, the fcntl function described in this article provides various means to further manage file descriptors. It can be used to perform various control operations on opened descriptors, for example, you can copy a file descriptor like DUP and dup2, and get or set the file descriptor flag (read-only, write-only, etc.) to manipulate the file lock.
Header file:
#include <unistd.h>#include <fcntl.h>
Define functions:
int fcntl(int filedes, int cmd);int fcntl(int filedes, int cmd, longarg);int fcntl(int filedes, int cmd,structflock *lock);
Return Value: If the return value is successful, the dependency and CMD are returned. If an error occurs, the return value is-1. if the attribute is set, 0 is returned correctly, and-1 is returned for the error. If the attribute is read, the attribute value is returned correctly, and-1 is returned for the error. for example, the following three commands have specific return values: f_dupfd, f_getfd, f_getfl, and f_getown.
F_dupfd: returns a new file descriptor.
F_getfd: returns the corresponding flag.
F_getfl and f_getown: return a process ID or a negative process group ID.
Function Description:
The first parameter of the function is the file descriptor of the attribute to be modified, and the third integer is always an integer or record lock (record lock is not discussed here). If it is a record lock, the third parameter points to a struct pointer.
Fcntl () performs various control operations on the opened file descriptor filedes. The specific operation is determined by the second cmd parameter. Table 1 lists all the allowed values of this parameter. according to the CMD value, some parameters must provide the third parameter, that is, the file lock.
Table 1 cmd value and description of the fcntl Function
Fcntl functions have five functions:
1) copy an existing file descriptor (cmd = f_dupfd ).
2) Get or set the file descriptor flag (cmd = f_getfd or f_setfd ).
3) Get or set the File status flag (cmd = f_getfl or f_setfl ).
4) obtain or set the asynchronous I/O ownership (cmd = f_getown or f_setown ).
5) obtain or set the record lock (cmd = f_getlk or f_setlf ).
2. f_dupfd: copy the file descriptor filefes. The new file descriptor returns the most function value. The new file descriptor has the following features:
(1) The new descriptor is the minimum value of each value in the unopened file descriptor that is greater than or equal to the third parameter value (positive integer.
(2) The new descriptor shares the same file table item with filedes (similar to the DUP function). That is, the new descriptor shares the same file pointer with the original filedes file, the same open file (or pipeline), the same file status flag, the same file mode. as shown in figure 2, the file descriptors FD = 3 and FD = 1 point to the same file table. however, the new file descriptor has its own set of file descriptor flag, and its fd_cloexec file descriptor flag is cleared.
(3) set the close-on-EXE flag associated with the new file descriptor to remain open between various exec (2) system calls.
When a process opens a file, the data structure 1 in the kernel is shown, that is, the kernel state is like this before the program copies the file descriptor. By default, only 1024 file descriptors can be opened for each process. When a process opens a file, the unused descriptors are searched from 0 by default. Because 0, 1 and 2 are occupied by default, generally, it starts from 3.
Figure 1 kernel data structure status when a process opens a file
File Table items: each open file corresponds to a file table, which can be shared. When multiple file descriptors point to the same file table, the refcnt field in the file table changes accordingly. the file table contains the File status identifiers: The file opening mode (R, W, RW, append, Noblock, etc.), the current file offset, refcnt: referenced quantity, V node pointer: point to a V node table.
V node table: each file corresponds to a V node table. No matter how many processes open the table, there is only one file. It includes the V node information (mainly the information in the stat struct ), I node information.
Simply put, the copy file descriptor only adds one item to the file table opened by the current process (Figure 2: added FD = 3 ), both (FD = 1 or FD = 3) point to the file table information in the kernel at the same time. Any operation file descriptor will affect another one.
Figure 2 kernel data structure status after the process copies the file descriptor
Example 1: copy the file descriptor and use the file descriptor before and after the copy to write information to the opened file.
# Include <unistd. h> # include <fcntl. h> # include <stdlib. h> # include <stdio. h> # include <string. h> void main () {int FD, newfd; char * buffd = "advanced programming! Write by FD \ n "; char * bufnewfd =" advanced programming! Write by newfd \ n "; FD = open (" test.txt ", o_rdwr | o_creat, 0644); If (FD =-1) {printf ("Open File error % m \ n"); exit (-1) ;}// Start copying newfd = fcntl (FD, f_dupfd ); // use FD to write (FD, buffd, strlen (buffd); close (FD); // use newfd to write (newfd, bufnewfd, strlen (bufnewfd )); if (close (newfd) =-1) {printf ("Close error \ n");} printf ("Now the content of file: \ n "); system ("cat test.txt"); exit (0 );}
Output:
: Advanced programming! Write by FD
: Advanced programming! Write by newfd
It can be seen that the same file is operated during read/write operations on FD or newfd, and after FD is disabled, newfd is not affected. newfd can also be used to operate open files.
For copying a file descriptor, The fcntl and DUP functions are similar.
Call:
dup(filedes);
It is equivalent:
fcntl(filedes, F_DUPFD, 0);
And call:
dup2(filedes,filedes2);
It is equivalent:
close(filedes2);fcntl(filesdes,F_DUPFD,filedes);
Note: In the latter case, dup2 is not exactly equivalent to close with fcntl. difference:
(1) dup2 is an atomic operation, while close and fcntl include two function calls. It is possible to insert and execute the signal capture function between close and fcntl. In this process, the file descriptor is modified.
(2) dup2 and fcntl have some different errno.
3. f_getfl is used to obtain the File status mark and its access mode. The file status mark corresponding to filedes is used as the flag supported by the returned value. f_getfl, as shown in table 2.
Table 2 File status flag description
Example 2: The current read permission of the monitoring file. If the file has read permission, the system returns readable information. If the file has write permission, the system returns writable information. Otherwise, the system Returns Error information.
#include <sys/types.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>int main(int argc, char *argv[]){ int accmode,val; if(argc!=2) { printf("error:\n"); } if((val=fcntl(atoi(argv[1]),F_GETFL,0))<0) { printf("error:%m\n"); exit(-1); } accmode = val & O_ACCMODE; switch(accmode) { case O_RDONLY: printf("read only\n"); break; case O_WRONLY: printf("write only\n"); break; case O_RDWR: printf("read write\n"); break; default: printf("unknow access mode\n"); } exit(0);}
Output:
:./A. Out test.txt
: Read Write
4. summary The three methods for copying file descriptors have learned almost the same. Remember the DUP, dup2, and fcntl functions, because they are used for a lifetime. there are still a lot of questions about the use of fcntl. Here we will start with a simple introduction and further study in the future.
--
Certificate ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Do not build a high station in the sand float, calm down and slowly accumulate -----------------------------------------Certificate ----------------------------------------------------------------------------------------------------------------------------------------------------------
Fcntl function details