文件控制函数 fcntl  手册翻译

来源:互联网 发布:知乎专栏赚钱 编辑:程序博客网 时间:2024/06/05 01:12
用了一个下午翻译的,有问题请指正
2004-10-13 17:55

文件控制函数
     fcntl -- file control

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <fcntl.h>;

     int
     fcntl(int fd, int cmd, ...);

[描述]
        Fcntl()针对(文件)描述符提供控制.参数fd 是被参数cmd操作(如下面的描述)的的描述符.
        针对cmd的值,fcntl能够接受第三个参数int arg

   
        F_DUPFD        返回一个如下描述的(文件)描述符:
                        o        最小的大于或等于arg的一个可用的描述符
                        o        与原始操作符一样的某对象的引用
                        o        如果对象是文件(file)的话,返回一个新的描述符,这个描述符与arg 共享相同的偏移量(offset)
                        o        相同的访问模式(读,写或读/写)
                        o        相同的文件状态标志(如:两个文件描述符共享相同的状态标志)
                        o        与新的文件描述符结合在一起的close-on-exec 标志被设置成交叉式访问execve(2)的系统调用
     
   
        F_GETFD        取得与文件描述符fd联合close-on-exec标志,类似FD_CLOEXEC.如果返回值和FD_CLOEXEC进行与运算结果是0的话,文件保 持交叉式访问exec(),否则如果通过exec运行的话,文件将被关闭(arg 被忽略)
     
   
        F_SETFD        如同上面描述的那样,在arg是o或者FD_CLOEXEC将fd的close-on-exec标志        设置给arg
     
  
        F_GETFL        取得fd的文件状态标志,如同下面的描述一样(arg被忽略)
     
  
        F_SETFL        设置给arg描述符状态标志
     
    
        F_GETOWN         取得当前正在接收SIGIO或者SIGURG信号的进程id或进程组id,进程组id返回成负值(arg被忽略)
     
  
        F_SETOWN        设置将接收SIGIO和SIGURG信号的进程id或进程组id,进程组id通过提供负值的arg来说明,否则,arg将被认为是进程id

  
        命令字(cmd)F_GETFL和F_SETFL的标志如下面的描述:
        O_NONBLOCK        非阻塞I/O;如果read(2)调用没有可读取的数据,或者如果write(2)操作将阻塞,read或write调用返回-1和EAGAIN错误
        O_APPEND                强制每次写(write)操作都添加在文件大的末尾,相当于open(2)的O_APPEND标志
        O_DIRECT                最小化或去掉reading和writing的缓存影响.系统将企图避免缓存你的读或写的数据.如果不能够避免缓存,那么它将最小化已经被缓存了的数据造 成的影响.如果这个标志用的不够好,将大大的降低性能
        O_ASYNC                当I/O可用的时候,允许SIGIO信号发送到进程组,例如:当有数据可以读的时候
   
   
       
        advisory档案锁可用的命令有下面这些:
 
        F_GETLK        通过第三个参数arg(一个指向flock的结构体)取得第一个阻塞lock description指向的的锁.取得的信息将覆盖传到fcntl()的flock结构的信息.如果没有发现能够阻止本次锁(flock)生成的锁,这 个结构将不被改变,除非锁的类型被设置成F_UNLCK.

    
        F_SETLK        按照指向结构体flock的指针的第三个参数arg所描述的锁的信息设置或者清除一个文件segment锁.F_SETLK被用来实现共享(或读)锁 (F_RDLCK)或独占(写)锁(F_WRLCK),同样可以去掉这两种锁(F_UNLCK).如果共享锁或独占锁不能被设置,fcntl()将立即返 回EAGAIN.

    
        F_SETLKW        除了共享锁或独占锁被其他的锁阻塞这种情况外,这个命令和F_SETLK是一样的.如果共享锁或独占锁被其他的锁阻塞,进程将等待直到这个请求能够完成. 当fcntl()正在等待文件的某个区域的时候捕捉到一个一个信号,如果这个信号没有被指定SA_RESTART,fcntl将被中断.

    
        当一个共享锁被set到一个文件的某段的时候,其他的进程可以set 共享锁到这个段或这个段的一部分.共享所阻止任何其他进程set独占锁到这段保护区域的任何部分.如果文件描述符没有以读的访问方式打开的话,共享锁的设置请求会失败

   
        独占锁阻止任何其他的进程在这段保护区域任何位置设置共享锁或独占锁.如果文件描述符不是以写的访问方式打开的话,独占锁的请求会失败

  
        1_whence 的可能值包括SEEK_SET,SEEK_CUR,和SEEK_END,这些值用来说明相对的偏移量,1_start 比特,将分别从文件的开头、当前位置、文档末尾算起,l_len的值是将被连续锁定的比特值.如果l_len是负值,结果将不被定义的.l_pid只跟 F_GETLK一起用用来返回拥有这个blocking锁的进程id.一个成功的F_GETLK请求后,l_whence的值将变成SEEK_SET

   
     much more efficient.        一个锁能开始于甚至延伸打当前文件的末尾,但是不能开始于或扩展到文件的开头以前.当l_len为0的时候,锁被设置成文件的最大的可能的偏移量.如果 l_whence和l_start指向文件的开始位置,并且l_len为0,整个文件将被锁定.如果一个程序只想锁定整个文档,系统调用flock(2) 将更有效率

        文件的每个字节最多只能设置一种类型的锁.在F_SETLK和F_SETLKW成功返回前,如果当前进程拥有一个已经存在的锁,并且锁住的区域在新 锁请求的区域内,则先前被设置的锁的每一个字节都将被新设置成新锁的类型.如上面描述共享锁和独占锁说明的那样,当另一个进程在指定的区域拥有任何跟请求 的锁类型相冲突的时候,对F_SETLK或F_SETLKW的请求将会失败或被阻塞.

   
     这个接口服从System V和IEEE Std 1003.1-1988 (``POSIX.1'')的"当一个进程关闭任何一个文件操作符的时候,这个文件的与给该进程所有关联的锁都会失效"这一相当stupid的语义.这一 语义意味着一个子程序库必须很清楚的知道它可能访问某个文件.例如:一个更新password文件的程序在进行更新操作的时候锁住了password文 件,然后调用getpwnam(3)来重新取得一条记录,这时候,这个锁就失效了.因为,getpwnam(3)打开,读取,并且关闭了password 数据库文件.数据库文件的关闭释放了所有的这个进程拥有的跟这个数据库文件相关的锁,即使这个操作(指getpwnam(3))并不需要跟这个数据库文件 相关联的锁.这个接口语义的另一个问题是锁不能被通过fork(2)创建的子进程继承.fork(2)接口有更多合理的理由和允许锁被子进程继承. Flock(2)被推荐用来一个程序希望确保它的锁的完整性以及希望将它的锁传给它的子进程.
     注意:flock(2)和fcntl(2)锁操作能够安全的同时使用但是如果文件描述符已经被另一个进程用flock(2)锁住,fcntl(F_GETLK)的l_pid返回值为-1

   
     当进程结束的时候,某一文件的给定进程的所有相关锁都会被删掉(失效)

     所有已经拥有的锁在调用execve(2)后依然起作用直到新的程序释放他们.如果新程序不知道这些锁,那么他们一直到程序结束的时候才会被释放.

   
     潜在的死锁在一个进程控制一个锁住的文件区域,但是在它试图睡眠等待被其他进程控制的锁解锁的时候就会发生.



返回值
        在成功执行的基础上,返回值根据cmd的不同返回
        F_DUPFD        一个新的文件描述符
        F_GETFD        标志值(只定义了low-order字节)
        F_GETFL        标志值
        F_GETOWN         文件描述符的所有者的值(我也不是很清楚是什么????)
        其他情况,返回-1并且errno被置值来判断错误

ERRORS
     Fcntl() will fail if:
错误
        下面的情况Fcntl()会失败

 
     [EAGAIN]        参数cmd是F_SETLK,锁的类型(l_type)是共享锁(F_RDLCK)或者是独占锁(F_WRLCK),将被锁定的那一段已经被另一个进程用 独占锁锁住;锁的类型是独占锁,将被锁定的那一段中有一部分已经被另一个进程用共享锁或独占锁锁住.

    
        [EBADF]        Fd不是一个有效的打开的文件描述符.
                        参数cmd是F_SETLK或F_SETLKW,锁的类型(l_type)是共享锁(F_RDLCK),并且fd不是一个有效的已经打开的可写文件描述符

        [EDEADLK]                参数cmd是F_SETLKW,检测到一个死锁

   
        [EINTR]        参数cmd是F_SETLKW,但是这个函数被一个信号中断

  
        [EINVAL]        cmd是F_DEPFD,arg是负值或者比允许的最大值大(参见getdtablesize(2))
                               
                                参数cmd是F_GETLK,F_SETLK或者F_SETLKW并且指向arg的数据不是有效的,或者fd指向的文件不支持锁

        [EMFILE]        参数cmd是F_DUPFD并且进程能用的文件描述符的最大值已经存在,或者不存在比arg大或相等的文件描述符

   
        [ENOLCK]        参数cmd是F_SETLK或F_SETLKW,并且????

   
        [EPERM]        参数cmd是F_SETOWN并且作为参数给定的进程ID或者进程组跟调用者不在同一会话中

    
        [ESRCH]        参数cmd是F_SETOWN但是作为参数给定的进程ID并不存在

    
     另外,如果fd引用的文件描述符是一个终端设备(与打开一个socket的描述符相对),cmd是F_SETWON会失败,原因同tcsetpgrp(3),cmd是F_GETOWN会失败,原因同 tcgetpgrp(3)

FreeBSD 4.9                    January 12, 1994                    FreeBSD 4.9 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1212626