Name------------fcntl
int fcntl(int fd, int cmd, ... /*arg*/) - ---------------manipulate file descriptor/*操作文件描述符*/
//要包含头文件:
#include <unistd.h>
#include <fcntl.h>
the function performs one of the operations described below on the open file descriptor fd,The operation is determined by cmd
/*函数会对打开的文件描述符执行下面那些被描述的操作,具体操作由参数cmd(命令)决定*/
the function can take an optional third argument. Whether or not this argument is required is determined by cmd.
/*函数会接受第三个可选的参数,这些参数是否需要由指定参数cmd决定*/
the required argument types is indicated parentheses after each cmd name,or void is specified if the argument is not required.
/*必需的参数的类型由每个参数cmd名字后面的圆括号里内容表明,如果参数是不需要的则会被指定void*/
/*******************************************************************************************************/
/***cmd***/
------------------------------------------------------------------------------------------------------------------------------------------------------------
Duplicating a file descriptor/*复制文件描述符*/
F_DUPFD(long)
Find the lowest numberd available file descriptor greater than or equal to arg and make it be a copy of fd.
this is diferent from dup2(2), which uses exactly the descriptor specified
/*寻找一个大于等于参数arg的可用最小编号的文件描述符并且作为参数fd的拷贝,这不同于函数dup2()需要一个精确已被指定的描述符*/
F_DUPFD_CLOEXEC(long)
As for F_DUPFD,but additionally set the close-on-exec flag for the duplicate descriptor.Specifying this flag permits a program
to avoid an addtional fcntl() F_SETFD operation to set the FD_CLOEXEC flag. For an explanation of why this flag is useful,see the
description of O_CLOEXEC in open(2)
/*和F_DUPFD一样,但是额外对拷贝的描述符的设置了close-on-exec标记。指定这个标志可让一个程序避免一个额外的fcntl()函数F_SETFD
(参数cmd)操作去设置FD_CLOEXC标记,至于这个标记为什么可用,详情请看open()函数中O_CLOEXEC标记的描述*/
Simple example:
int main()
{
int fd1 = open("b.txt",O_CREAT|O_RDWR|O_EXCL,0666);
/*此时一般来说fd = 3, 0,1,2为linux系统占用*/
int newfd1 = fcntl(fd1, F_DUPFD,5);
/*此时一般来说newfd1 = 5 */
int newfd2 = fcntl(fd1, F_DUPFD,5);
/*此时newfd2 = 6,因为大于等于5的最小可用编号*/
int newfd3 = fcntl(fd1, F_DUPFD_CLOEXEC, 1);
/*应该newfd3 = 4,大于等于1且最小没有被占用的编号*/
return 0;
}
-------------------------------------------------------------------------------------------------------------------------------------
File descriptor flags /*文件描述符标记*/
the following commands manipulate the flags associated with a file descriptor. Currently, only one such flags is defined:
FD_CLOEXEC,the close-on-exec flag. if the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2),otherwise
it will be closed
/*下面的命令操控文件描述符相关的标记,当前只有一个标记被定义:FD_CLOEXEC。如果FD_CLOEXC位是0,文件描述符在execve()系列函数
中依然是打开可用的,否则它将被关闭*/
F_GETFD(void)
Read the file descriptor flags; arg is ignored;
读取文件描述符标记,参数被忽略
F_SETFD(long)
Set the file descriptor flags to the value specified by arg;
将文件描述符标记设置为参数arg指定的值
-----------------------------------------------------------------------------------------------------------------------------------------------
File status flags /*文件状态标记*/
Each open file description has certain associated status flags, initialized by open() and possibly modified by fcntl().Duplicated file
descriptors refer to the same open file description, and thus share the same file status flags
the file status flags and their semantics are described in open();
/*每个打开的文件表都必然有相关的状态标记,这标记由open函数初始化也可能被fcntl函数修改。拷贝的文件描述符都指向相同的打开的文件表
因此共享同样的文件状态标记*/
F_GETFL(void)
Read the file status flags; arg is ignored;
读取文件状态标记,忽略参数arg(注意:O_CREAT标记是一次性标记,无法由该操作获取);
F_SETFL(long)
Set the file status flags to the value specified by arg. File access mode (O_RDONLY , O_WRONLY, O_RDWR) and file creation
flag(O_CREAT, O_EXCL, O_NOCTTY,O_TRUNC) in arg are ignored, On linux this command can only change the O_APPEND,O_ASYNC,
O_DIRECT,O_NOATIME,and O_NONBLOCK flags.
/*设置文件状态标记为参数指定的值,文件访问模式和文件创建标记被忽略,在linux系统中这个命令仅仅改变......标记*/
Simple example:
int main()
{
int fd = open("b.txt",O_CREAT|O_EXCL|O_RDWR,0666);
long flags = fcntl(fd, F_GETFL);
/*此时flags = O_EXCL | O_RDWR, O_CREAT标记位在执行open函数后变为0,*/
int res = fcntl(fd, F_SETFL , O_APPEND | O_WRONLY | O_TRUNC);
flags = fcntl(fd, F_GETFL);
/*此时flags 只多了 O_APPEND位 O_WRONLY,O_TRUNC都被忽略掉,无法修改*/
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Advisory locking (Emphasis) /*访问锁(重点)*/
F_GETLK , F_SETLK and F_SETLKW are used to acquire , release, and test for the existence of record locks(also know as file-segment
or file-region lock), The third argument, lock , is a pointer to a structure that has at least the following fileds (in unspecified order)
/* F_GETLK , F_SETLK 和 F_SETLKW 是用来申请,释放,测试一个存在的记录锁(如所知的文件段锁,文件域锁),第三个参数lock是指向一个至少
有如下区域的结构体*/
struct flock{
...
short l_type; //Type of lock: F_RDLCK,F_WRLCK,F_UNLCK;
short l_whence; //How to interpert l_start:SEEK_SET,SEEK_CUR,SEEK_END 文件seek的位置
off_t l_start; //Starting offset for lock 锁的偏移量
off_t l_len; //Number of bytes to lock 要锁定的字节数
pid_t l_pid; //PID of process blocking our lock(F_GETLK only); 阻塞我们锁的进程
...};
the l_start,l_start,,and l_len fields of this structure specify the range of bytes we wish to lock, Bytes past the end of file my be locked
,but not bytes before the start of the file.
/*结构体的l_start,l_whence,l_len区域制定我们想要lock的范围,越过文件尾的字节可能被lock,但是文件开头之前的字节不会*/
In the final two cases , l_start can be a negative number provided the offset does not lie before the start of the file
/*最后第二种情况,l_start可能是提供一个不位于文件开头之前的位置偏移量的负数*/
Specifying 0 for l_len has the special meaning:lock all bytes staring at the location specified by l_whence and l_start through to
to the end of file ,no matter how large the file grows.
/*指定参数l_len为0有特别的意义:lock所有从l_whence和l_start到文件尾的位置,无论文件选区域有多大*/
F_SETLK(struct flock*)
Aquire a lock(when l_type is F_RDLCK ro F_WRLCK) or release a lock(when l_type is F_UNLCK)on the bytes specified by the l_whence,l_start,and l_len fields of lock.If a conflicting lock is held by another process,this call return - 1 and sets errno to EACCES or
EGAIN
/*请求一个lock(当l_type是F_RDLCK或者F_WRLCK),或者释放一个lock(l_type是F_UNLCK),当lock被另外一个进程占用产生冲突,这次调用返回-1
同时设置错误errno为EACCES或者EGAIN*/
F_SETLKW(struct flcok*)
As for F_SETLK,but if a conflicting lock is held on the file , then wait for that lock to be release. If a signal is caught while waiting.
then the call is interrupted and returns immediately
/*同F_SETLK,此外在文件中lock冲突产生,这时会等待lock被释放,如果在等待时收到一个信号处理,这时调用会中断,并立即返回*/
F_GETLK(struct flock*)
On input to this call, lock describes a lock we would like to place on the file . if the lock could be placed, fcntl()does not actually
place it , but returns F_UNLCK in the l_type field of lock and leaves the other fields of the structure unchanged. if one or more incompatible
locks would prevent this lock being placed, then fcntl() returns details about one of these locks in the l_type, l_whence,l_start,andl_len fields
of lock and set l_pid to be PID of the process holding that lock
/*在这个调用输入中,参数lock描述了一个我们想要在文件中获取的lock信息,如果lock信息可以被获取,fcntl()函数不会真的获取它,而是在参数lock的l_type中返回F_UNCLK不会改变结构体中其他的值,如果有一个或者多个冲突的lock存在将会阻止lock信息获取,这时fcntl()函数返回这些锁的详细信息并设置拥有这个lock的进程的PID*/