Linux-Function-fcntl (一);

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*/

时间: 2024-10-21 17:00:53

Linux-Function-fcntl (一);的相关文章

linux function

#!/bin/bash function sayHello() { #这里的{ 和它前面的)之间可以没有空格 echo "Hello $1" } sayHello 'Neeky'

ftrace: tracing linux function calls

First confirm that you have root privilege. Second check the config of kernel that you have the configs on: CONFIG_FTRACE=y CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_EVENT_TRACING=y CONFIG_FUNCTION_TRACER CONFIG_STACK_TRACER CONFIG_DYNAMIC_FTRACE Last yo

Linux文件锁学习-flock, lockf, fcntl

参考  linux中fcntl().lockf.flock的区别 这三个函数的作用都是给文件加锁,那它们有什么区别呢? 首先flock和fcntl是系统调用,而lockf是库函数.lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文件加锁的效果也是一样的.后面分析不同点时大多数情况是将fcntl和lockf放在一起的. 下面首先看每个函数的使用,从使用的方式和效果来看各个函数的区别. 1. flock l 函数原型 #include<sys/file.h> i

Linux 应用程序 之 IO编程(一)

我的linux 环境是windows8.1 + VMware6.5.1+  Fedora14,参考书籍:第六章 链接:Linux应用程序开发详解(1-11).pdf 我利用一个SSH软件SSH Secure File Transfer Client 来从Linux传输文件 来张虚拟机运行Fedora的图: 下面步入正题: IO最基本操作: 1 //hello.c 2 #include <unistd.h> 3 #include <sys/types.h> 4 #include &l

socket在windows下和linux下的区别

windows到Linux代码移植遇到的问题 1.一些常用函数的移植 http://www.vckbase.com/document/viewdoc/?id=1586 2.网络 ------ 转载 & 修改(待整理) socket相关程序从windows移植到linux下需要注意的 1)头文件 windows下winsock.h/winsock2.h linux下sys/socket.h 错误处理:errno.h 2)初始化 windows下需要用WSAStartup linux下不需要 3)关

TCP/UDP网络编程的基础知识与基本示例(windows和Linux)

一.TCP编程的一般步骤 服务器端: 1.创建一个socket,用函数socket() 2.绑定IP地址.端口等信息到socket上,用函数bind() 3.开启监听,用函数listen() 4.接收客户端上来的连接,用函数accept() 5.收发数据,用函数send()和recv(),或者read()和write() 6.关闭网络连接 7.关闭监听 客户端: 1.创建一个socket,用函数socket() 2.设置要连接的对方IP地址和端口等属性 3.连接服务器,用函数connect()

Windows Socket和Linux Socket编程的区别 ZZ

socket相关程序从Windows移植到Linux下需要注意的: 1)头文件 Windows下winsock.h/winsock2.h Linux下sys/socket.h 错误处理:errno.h 2)初始化 Windows下需要用WSAStartup Linux下不需要 3)关闭socket Windows下closesocket(...) Linux下close(...) 4)类型 Windows下SOCKET Linux下int 如我用到的一些宏: #ifdef WIN32 typed

【转】Windows Socket和Linux Socket编程有什么区别

socket相关程序从Windows移植到Linux下需要注意的: 1)头文件 Windows下winsock.h/winsock2.h Linux下sys/socket.h 错误处理:errno.h 2)初始化 Windows下需要用WSAStartup Linux下不需要 3)关闭socket Windows下closesocket(...) Linux下close(...) 4)类型 Windows下SOCKET Linux下int 如我用到的一些宏: #ifdef WIN32 typed

一个php多态性的小例子

多态性在 OO 中指 "语言具有以不同方式处理不同类型对象的能力",但 PHP 是弱类型语言,在这一点上就比较弱,仅有 instance of 可以用于判断对象的类型 多态性的优点:让代码更接近生活中的真实情况 一下是一个非常简单的多态性例子,描述在电脑上安装不同操作系统,linux, OS X, windows 和 computer 是两种不同类型的对象. interface os{ function name(); function creator(); } class linux

DELPHI中的多线程【深入VCL源码】

线程的基础知识 线程的组成.线程有两部分组成. 1.一个是线程的内核对象,操作系统用它来对线程实施管理.内核对象也是系统用来存放线程统计信息的地方. 2.另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量. 进程从来不执行任何东西,它只是线程的容器.线程总是在某个进程环境中创建的,而且它的整个寿命期都在该进程中.这意味着线程在它的进程地址空间中执行代码,并且在进程的地址空间中对数据进行操作.因此,如果在单进程环境中,你有两个或多个线程正在运行,那么这两个线程将共享单个地址空