博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
fcntl函数用法——操纵文件描述符状态
阅读量:5119 次
发布时间:2019-06-13

本文共 3185 字,大约阅读时间需要 10 分钟。

fcntl函数:操纵文件描述符,改变已经打开的文件的属性

int fcntl(int fd, int cmd, ... //arg  );
cmd选项:
一、复制文件描述符:F_DUPFD
二、更改设置文件描述标志:F_GETFD 、F_SETFD  文件描述符标志,是体现进程的文件描述符的状态.
当前只定义了一个文件描述符标志FD_CLOEXEC。
   0: exec时不关闭已经打开的文件描述符
   1: exec时关闭已经打开的文件描述符
三、获取或者设置文件状态标识:F_GETFL、 F_SETFL(读写追加阻塞等等)
    文件状态标签中的标志可分为三类:访问方式、打开时标志和I/O操作方式。
 1. 访问方式 访问方式指明允许文件描述字用于读、写或两者兼之,包括O_RDONLY、O_WRONLY和O_RDWR。
这些访问方式在文件被打开时选定,之后便不能再改变。
 2、打开时标志指明打开文件时影响open()行为的一些选项。这些选项一旦文件打开就不保留,
但有一个例外是O_NONBLOCK,因为O_NONBLOCK同时也是一个I/O操作方式,故此标志被保留例如:O_CREAT
 3、I/O操作方式:I/O操作方式影响使用文件描述字进行输入输出操作的工作方式。这些标志由open()设置,
之后可以用fcntl()获取和改变。O_APPEND、O_NONBLOCK、O_SYNC等
四、设置获取文件锁:F_GETLK、F_SETLK,F_SETLKW

 

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #define ERR_EXIT(m)\10 do\11 {\12 perror(m);\13 exit(EXIT_FAILURE);\14 }while(0) //宏要求一条语句15 void set_flags(int fd,int flags);16 void clr_flags(int fd,int flags);17 int main(int argc,char*argv[])18 {19 char buf[1024]={ 0};20 int ret;21 /* flags=fcntl(0,F_GETFL,0);//先获取标准输入的标志22 if(flags==-1)23 ERR_EXIT("fcntl get flags error");24 ret=fcntl(0,F_SETFL,flags|O_NONBLOCK);//将标准输入设置为非阻塞,默认对读是阻塞的。不更改其他状态25 if(ret==-1)26 ERR_EXIT("fcntl set flags error");27 */ set_flags(0,O_NONBLOCK);//设置非阻塞,直接返回 (EAGIAN)read error: Resource temporarily unavailable(资源暂且不可用),如果是socket,会返回EWOUDBOCK28 //clr_flags(0,O_NONBLOCK);//清除29 ret=read(0,buf,1024);//标准输入读,read标准输入0默认阻塞(文件状态标志)30 if(ret==-1)31 ERR_EXIT("read error");32 printf("buf=%s\n",buf);33 return 0;34 }35 void set_flags(int fd,int flags)36 {37 int val;38 val=fcntl(fd,F_GETFL,0);//先获取标准输入的标志39 if(val==-1)40 ERR_EXIT("fcntl get flags error");41 val |=flags;42 if(fcntl(fd,F_SETFL,val)<0)43 ERR_EXIT("fcntl set flags error");44 }45 void clr_flags(int fd,int flags)//清除状态46 {47 int val;48 val=fcntl(fd,F_GETFL,0);//先获取标准输入的标志49 if(val==-1)50 ERR_EXIT("fcntl get flags error");51 val&=(~flags);//原状态中与上 flags 的反52 if(fcntl(fd,F_SETFL,val)<0)53 ERR_EXIT("fcntl set flags error");54 }

 

下面的例子讲解fcntl更改设置文件描述标志:

1 //hello.c 2 #include
3 #include
4 //hello程序打印程序环境变量 5 extern char** environ;//指针的指针,指向一个指针数组 environ-->[...]数组中每一项指向一个环境信息。例如"TERM=VI00","SHELL=/bin/bash" 6 int main(void) 7 { 8 printf("hello pid=%d\n",getpid()); 9 //打印环境变量10 int i;11 for(i=0;environ[i]!=NULL;i++)12 {13 printf("%s\n",environ[i]);14 }15 return 0;16 }17 18 //ececlp.标准输出在execlp中已经关闭,无法使用19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #define ERR_EXIT(m)\26 do\27 {\28 perror(m);\29 exit(EXIT_FAILURE);\30 }while(0) //宏要求一条语句31 int main()32 {33 printf("Entering main...\n");34 int flag=fcntl(1,F_GETFD);35 int ret=fcntl(1,F_SETFD,flag|FD_CLOEXEC);//标准输出EXEC位置136 if(ret==-1)37 perror("fcntl");38 //使用exec执行的程序里,此描述符被关闭,不能再使用它39 execlp("./hello","hello",NULL);//ececlp替换是成功的,但是标准输出EXEC位已经被置位,所以hello无法输出。40 /*输出结果41 Entering main...42 */43 printf("Exiting main...\n");//不输出了44 return 0;45 }

 

转载于:https://www.cnblogs.com/wsw-seu/p/8289741.html

你可能感兴趣的文章
深信服,前端面试
查看>>
ArcGIS 的 Oracle 数据库的要求
查看>>
大数据经典学习路线(及供参考)
查看>>
XMPP协议学习笔记二
查看>>
uva 1426 离散平方根
查看>>
[usaco]丑数
查看>>
【转】浅谈 C++ 中的 new/delete 和 new[]/delete[]
查看>>
adb server is out of date. killing...
查看>>
uva 10721 - Bar Codes(dp)
查看>>
nmon的使用
查看>>
IIS已停止工作
查看>>
降低Redis内存占用
查看>>
干程序员这么多年,没有自己的标签库怎么哪的出手?
查看>>
推介一个学习JAVA的系列教程-狗鱼IT教程
查看>>
Python 字典与集合
查看>>
php头函数和浏览器缓存
查看>>
java基础—面向对象
查看>>
【Java】判断IP是否内网(使用正则表达式)
查看>>
android 调用.NET WebServices
查看>>
cv论文(Low-rank相关)
查看>>