Function Description: Manipulate file characteristics According to the file description.
#include <unistd.h>
#include <fcntl.h>
int fcntl (int fd, int cmd);
int fcntl (int fd, int cmd, long arg);
int fcntl (int fd, int cmd, struct flock *lock);
Description
FCNTL () provides control over (file) descriptors. The parameter FD is a descriptor of the parameter CMD operation (as described below). For a value of CMD, Fcntl can accept the third argument, int arg.
[Return value]
The return value of Fcntl () is related to the command. If there is an error, all commands return-1, and if successful, some other value is returned. 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 return the corresponding flag
F_GETFL, F_getown returns a positive process ID or a negative process group ID
There are 5 functions of the FCNTL function:
1. Copy an existing descriptor (CMD=F_DUPFD).
2. Get/Set the file descriptor tag (CMD=F_GETFD or F_SETFD).
3. Get/Set the file status tag (CMD=F_GETFL or F_SETFL).
4. Get/Set asynchronous I/O ownership (Cmd=f_getown or F_setown).
5. Get/Set record lock (CMD=F_GETLK, f_setlk or f_setlkw).
1. F_DUPFD of the CMD value:
F_DUPFD returns a (file) descriptor as described below:
• A minimum of one of the available descriptors greater than or equal to ARG
• Reference to an object like the original operator
• If the object is a file, a new descriptor is returned that shares the same offset as ARG (offset)
• Same access mode (read, write or read/write)
• Same file status flag (e.g.: Two file descriptors share the same status flag)
• The CLOSE-ON-EXEC flag that is combined with the new file descriptor is set as a system call for cross-access Execve (2)
Actually invoke the DUP (OLDFD);
is equivalent to
Fcntl (OLDFD, F_DUPFD, 0);
and call Dup2 (OLDFD, NEWFD);
is equivalent to
Close (OLDFD);
Fcntl (OLDFD, F_DUPFD, NEWFD);
2. F_getfd and f_setfd of the CMD value:
F_GETFD obtains the CLOSE-ON-EXEC flag associated with the file descriptor FD, similar to fd_cloexec. If the return value and Fd_cloexec are 0, the file remains interleaved with exec (), otherwise the file will be closed (Arg ignored) if it is run through exec
F_SETFD sets the CLOSE-ON-EXEC flag, which is determined by the fd_cloexec bit of the parameter arg, and it should be understood that many of the existing programs involving file descriptor flags do not use constant fd_cloexec, but instead set this flag to 0 (system default, Do not close at exec) or 1 (off at exec)
Caution must be taken when modifying the file descriptor flag or file status flag to obtain the current flag value, then modify it as desired, and finally set the new flag value. You cannot just execute the F_SETFD or F_SETFL command, which turns off the previously set flag bit.
3. F_GETFL and F_SETFL of the CMD value:
F_GETFL obtains the file status flag of FD, as described below (ARG is ignored), when describing the open function, it is stated
The file status flag. Unfortunately, three access-mode flags (O_rdonly, o_wronly, and O_RDWR) do not account for 1. (The values for these three flags are 0, 1, and 2, and for historical reasons, these three values are mutually exclusive-only one of these three values can be found in a file.) So first it is necessary to use the shielding character o_accmode and to obtain the access mode bit, and then compare the result with these three kinds of values.
F_SETFL set to the ARG descriptor status flag, several flags that can be changed are: O_append,o_nonblock,o_sync and O_async. There are 7 file status flags in Fcntl: O_rdonly, O_wronly, O_rdwr, O_append, O_nonblock, O_sync and O_async
Several flags that can be changed are described below:
O_nonblock non-blocking I/O if the Read (2) call does not have readable data, or if the write (2) operation is blocked, the read or write call will return 1 and Eagain error
O_append force each write operation to be added at the end of the file, equivalent to the O_APPEND flag of open (2)
O_direct minimizes or removes the cache impact of reading and writing. The system will attempt to avoid caching your read or write data. If it is not possible to avoid caching, it will minimize the impact of data that has already been cached. If the logo is not good enough, it will greatly reduce the performance
O_async allows the Sigio signal to be sent to the process group when I/O is available, for example: when there is data to read
4. F_getown and F_setown of the CMD value:
F_getown Gets the process ID or process group ID that is currently receiving the Sigio or Sigurg signal, and the process group ID returns a negative value (ARG is ignored)
F_setown sets the process ID or process group ID of the Sigio and Sigurg signals to be received, and the process group ID is described by providing a negative value of ARG (a process group ID for the absolute value of arg), otherwise ARG will be considered a process ID
5. Cmd value of f_getlk, f_setlk or f_setlkw: Get/Set record lock function, successful return 0, if there is an error return-1, the reason for the error is stored in the errno.
F_GETLK obtains the first blocking lock description point by using the third parameter, ARG (a struct that points to flock). The information obtained will overwrite the information of the flock structure uploaded to Fcntl (). If no locks are found to block this lock (flock), the structure will not be changed unless the type of the lock is set to F_unlck
F_SETLK Sets or clears the segment lock of a file according to the information about the lock described by the third argument to the pointer to struct flock, Arg. F_SETLK is used to implement shared (or read) locks (F_RDLCK) or exclusive (write) locks (f_wrlck), which can also be removed from both locks (f_unlck). If a shared or exclusive lock cannot be set, Fcntl () will return immediately eagain
F_SETLKW This command is the same as F_SETLK except for shared or exclusive locks that are blocked by other locks. If a shared or exclusive lock is blocked by another lock, the process waits until the request can be completed. When Fcntl () is waiting for an area of the file to capture a signal, if the signal is not specified Sa_restart, Fcntl will be interrupted
When a shared lock is set to a segment of a file, other processes can set a shared lock to this segment or part of the segment. A shared lock prevents any other process set from being exclusively locked into any part of this protected area. If the file descriptor is not opened with read access, the set request for the shared lock will fail.
An exclusive lock prevents any other process from setting a shared or exclusive lock anywhere in this protected area. If the file descriptor is not opened with write access, the exclusive lock request fails.
Pointer to struct flock:
struct FLCOK
{
short int l_type; /* Locked Status */
The following three parameters are used for the segmentation of the file lock, if the entire file lock, then: L_whence=seek_set, L_start=0, l_len=0
short int l_whence; /* Decide L_start location */
off_t L_start; /* Start position of locked area */
off_t L_len; /* Size of locked area */
pid_t L_pid; /* Process for locking actions */
};
There are three states of L_type:
F_rdlck creating a lock for reading
F_wrlck creating a lock for write-in
F_unlck Delete a previously established lock
There are three ways of L_whence:
Seek_set starting position of the lock with the beginning of the file
Seek_cur starting position with the current file read and write location as locked
Seek_end start position with end of file as lock
There are two types of fcntl file locks: recommended and mandatory locks
The recommended lock is this: each process that uses a locked file checks to see if there is a lock and, of course, respects the existing lock. The kernel and system generally insist on not using recommended locks, which rely on programmers to comply with this rule.
A mandatory lock is performed by the kernel: When a file is locked for writing, the kernel blocks any read or write access to the file before the process that locks it is released, and each read or write access checks to see if the lock exists.
System default Fcntl are recommended locks, mandatory locks are non-POSIX standard. If you want to use a mandatory lock, to make the entire system can use a mandatory lock, you need to re-mount the file system, mount using the parameters-0 mand to open a mandatory lock, or close the locked file group execution permissions and open the file's set-gid permission bit.
Recommended locks are only used between cooperating processes. The understanding of the cooperating process is most important, referring to processes that affect other processes or processes that are affected by other processes, with two examples:
(1) We can run the same command in two windows simultaneously and operate on the same file, then these two processes are cooperating processes
(2) Cat file | Sort, then the process that the cat and sort produces is the cooperating that uses the pipe processes
I/O operations using the Fcntl file lock must be careful: how the process handles the lock before starting any I/O operations, and how to do all of the operations before unlocking the file must be considered. If the file is opened before the lock is set, or if the file is closed after the lock is read, another process may access the file within a fraction of a second between the lock/unlock operation and the on/off operation. When a process locks a file, regardless of whether it releases the added lock, as long as the file is closed, the kernel automatically releases the proposed lock on the file (which is also the biggest difference between the proposed and mandatory locks), so do not want to set up a proposed lock to achieve the purpose of permanently not allowing other processes to access the file (mandatory lock) ; A mandatory lock works for all processes.
FCNTL uses three parameters f_setlk/f_setlkw, F_unlck and f_getlk to separate request, release, Test record locks. Record locks is a lock on a file rather than an entire file, and this meticulous control allows the process to collaborate better to share file resources. Fcntl can be used to read and write locks, and read lock is also called shared lock, because multiple cooperating process can establish a read lock on the same part of the file; write lock is called exclusive lock (Repel lock ), because at any moment there can be only one cooperating process to establish a write lock on a part of the file. If cooperating processes the file, they can add read lock to the file at the same time, and before a cooperating process adds write lock, the other cooperating must be released The process adds read lock and Wrtie lock to the file, meaning that only one write lock exists for the file, and read lock and Wrtie lock cannot coexist.
The following example uses F_GETFL to get the file status flags for FD.
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <errno.h>
using namespace Std;
int main (int argc,char* argv[])
{
int FD, VAR;
Fd=open ("new", O_RDWR);
if (argc!=2)
{
Perror ("--");
cout<< "Please enter the parameter, that is, the file name! "<<endl;
}
if ((Var=fcntl (Atoi (argv[1), F_GETFL, 0)) <0)
{
Strerror (errno);
cout<< "fcntl file error." <<endl;
}
Switch (var & o_accmode)
{
Case o_rdonly:cout<< "Read only." <<endl;
Break
Case o_wronly:cout<< "Write only.." <<endl;
Break
Case o_rdwr:cout<< "Read wirte." <<endl;
Break
Default:break;
}
if (Val & o_append)
cout<< ", append" <<endl;
if (Val & O_nonblock)
cout<< ", noblocking" <<endl;
cout<< "Exit 0" <<endl;
Exit (0);
}
The fcntl of pleasant Goat and Goat Series