fcntl函数用法——操纵文件描述符状态
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<unistd.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include<string.h>
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,会返回EWOUDBOCK
28 //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<unistd.h>
3 #include<stdio.h>
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<unistd.h>
20 #include<sys/types.h>
21 #include<stdlib.h>
22 #include<stdio.h>
23 #include<errno.h>
24 #include<fcntl.h>
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位置1
36 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 }
fcntl函数用法——操纵文件描述符状态的更多相关文章
- fcntl函数用法——复制文件描述符
文件描述符复制和输出重定向dup() 用最小的文件描述符来复制,从0开始搜素.复制文件描述符后,最小文件描述符指向被复制描述符指向的文件.dup2(int oldfd,int newfd) 强制用ne ...
- linux系统编程之文件与IO(八):文件描述符相关操作-dup,dup2,fcntl
本节目标: 1,文件共享 打开文件内核数据结构 一个进程两次打开同一个文件 两个进程打开同一个文件 2,复制文件描述符(dup.dup2.fcntl) 一,文件共享 1,一个进程打开两个文件内核数据结 ...
- UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符
lienhua342014-08-23 UNIX 提供了两个函数 dup 和 dup2 用于复制一个现存的文件描述符. #include <unistd.h> int dup(int fi ...
- Unix系统编程()复制文件描述符
Bourne shell的IO重定向语法2>&1,意在通知shell把标准错误(文件描述符2)重定向到标准输出(文件描述符1).因此下列命令将把标准输出和标准错误写入result.log ...
- 文件描述符file descriptor与inode的相关知识
每个进程在Linux内核中都有一个task_struct结构体来维护进程相关的 信息,称为进程描述符(Process Descriptor),而在操作系统理论中称为进程控制块 (PCB,Process ...
- Linux中通过Socket文件描述符寻找连接状态介绍
针对下文的总结:socket是一种文件描述符 进程的打开文件描述符表 Linux的三个系统调用:open,socket,pipe 返回的都是一个描述符.不同的进程中,他们返回的描述符可以相同.那么,在 ...
- dup等复制文件描述符函数
[root@bogon code]# cat b.c #include<stdio.h> #include<error.h> #include<unistd.h> ...
- 进程间传递文件描述符——sendmsg和recvmsg函数
先引入一个例子,该程序的目的是子进程向父进程传递文件描述符,并通过该文件描述符读取buf. #include <func.h> int main(){ int fds[2]; pipe(f ...
- linux fcntl 对文件描述符控制
linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制
随机推荐
- Python中列表、元组、字典、集合与字符串,相关函数,持续更新中……
本篇博客为博主第一次学 Python 所做的笔记(希望读者能够少点浮躁,认真阅读,平心静气学习!) 补充: 列表.元组和字符串共同属性: 属于有序序列,其中的元素有严格的先后顺序 都支持双向索引,索引 ...
- js拖拽上传 文件上传之拖拽上传
由于项目需要上传文件到服务器,于是便在文件上传的基础上增加了拖拽上传.拖拽上传当然属于文件上传的一部分,只不过在文件上传的基础上增加了拖拽的界面,主要在于前台的交互, 从拖拽的文件中获取文件列表然后调 ...
- spring boot:使用分布式事务seata(druid 1.1.23 / seata 1.3.0 / mybatis / spring boot 2.3.2)
一,什么是seata? Seata:Simpe Extensible Autonomous Transcaction Architecture, 是阿里中间件开源的分布式事务解决方案. 前身是阿里的F ...
- fedora30平台安装docker 19.03
一,下载docker 1,说明:docker的打包对于fedora的支持很及时, 所以在fedora 30/31上都可以直接使用官方的rpm包 下载地址: https://download.docke ...
- 智能DNS的实现
网络路径远,导致用户访问延迟 各个运营商之间的带宽有阀口. GSLB 就近的返回服务器的地址 CDN网络 内容分发网络 Content Delivery Network CND服务商 阿里 腾讯 蓝汛 ...
- Linux命令之Hash缓存表
Hash缓存表 系统初始hash表为空,当外部命令执行时,默认会从PATH路径下寻找该命令,找到后会将这条命令的路径记录到hash表中,当再次使用该命令时,shell解释器首先会查看hash表,存在将 ...
- 一口气看完45个寄存器,CPU核心技术大揭秘
序言 前段时间,我连续写了十来篇CPU底层系列技术故事文章,有不少读者私信我让我写一下CPU的寄存器. 寄存器这个太多太复杂,不适合写故事,拖了很久,总算是写完了,这篇文章就来详细聊聊x86/x64架 ...
- 微信小程序-基于高德地图API实现天气组件(动态效果)
微信小程序-基于高德地图API实现天气组件(动态效果) 在社区翻腾了许久,没有找到合适的天气插件.迫不得已,只好借鉴互联网上的web项目,手动迁移到小程序中使用.现在分享到互联网社区中,帮助后续有 ...
- WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构.该架构的项层为服务模型层. 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型. ...
- Bitmap缩放(三)
质量压缩 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle ...