当前位置: 代码迷 >> 综合 >> 基础函数(fcntl、dup、dup2)
  详细解决方案

基础函数(fcntl、dup、dup2)

热度:22   发布时间:2023-12-02 01:25:31.0

1、fcntl函数—改变已经打开文件的属性

函数原型:
这里写图片描述
该函数有五种功能:
(1)复制一个现有的描述符(cmd=F_DUPFD),新的文件描述符作为函数的返回值。
(2) 获得/设置文件描述符标记(cmd=FGETFD 或 FSETFD). (3)获得/设置文件状态标记(cmd=FGETFL 或 FSETFL). (4)获得/设置异步I/O所有权(cmd=FGETOWN 或 (FSETOWN).
(5)获得/设置记录锁(cmd=FGETLK,FSETLK或F_SETLKW)
返回值:若成功,依赖于传入的cmd;若出错,则返回-1

2、重定向函数dup和dup2

函数原型:
这里写图片描述
函数说明:
(1)由dup返回的新文件描述符一定是当前可用文件描述符中的最小值
(2)对于dup2,可用newfd参数指定新描述符的值,如果newfd已经打开,则先将其关闭,若newfd等于oldfd,则dup2返回newfd,而不关闭它。
(3)返回值:对于这两个函数,若成功,返回新的文件描述符,若出错,返回-1

3、轮询方式读取标准输入

基于fcntl函数,我们可以实现SetNoBlock函数,将文件描述符设置为非阻塞:
函数具体实现过程如下:

 1 #include<stdio.h>2 #include<unistd.h>3 #include<fcntl.h>4 5 void SetNoBlock(int fd)6 {7     int f1=fcntl(fd,F_GETFL);8     if(f1<0)9     {10         perror("fcntl");11         return ;12     }13     fcntl(fd,F_SETFL,f1|O_NONBLOCK);14 }
15 //使用F_GETFL将当前的文件描述符的属性取出来(这是一个位图). 然后再使     用FSETFL将文件描述符设置回去设置回去的同时 , 加上一个 ONONBLOCK参数.16 int main()17 {18     SetNoBlock(0);19     while(1)20     {21         char buf[1024]={0};22         ssize_t s=read(0,buf,sizeof(buf)-1);23         if(s<0)24         {25             perror("read");26             sleep(1);27             continue;28         }29         printf("input:%s\n",buf);30     }31     return 0;32 }

运行结果:
这里写图片描述
该进程,没有等待写就返回了,是非阻塞的。

4、使用dup将标准输出重定向到文件中

具体代码:

 1 #include<stdio.h>2 #include<unistd.h>3 #include<fcntl.h>4 5 int main()6 {7     int fd=open("./log",O_CREAT|O_RDWR);8     if(fd<0)9     {10         perror("open");11         return 1;12     }13     close(1);14     int newFd=dup(fd);15     if(newFd!=1)16     {17         perror("dup");18         return 1;19     }20     printf("newFd:%d\n",newFd);21     close(fd);22 23     for(;;)24     {25         char buf[1024]={0};26         ssize_t s=read(0,buf,sizeof(buf)-1);27         if(s<0)28         {29             perror("read");30             continue;31         }32         printf("%s",buf);33         fflush(stdout);34     }35     close(newFd);36     return 0;37 }

运行结果:
写入数据
这里写图片描述
打开./log文件,查看刚刚写入的文件:
这里写图片描述

5、用dup2将标准输出重定向到文件中

具体代码:

  1 #include<stdio.h>2 #include<unistd.h>3 #include<fcntl.h>4 5 int main()6 {7     int fd=open("./log",O_CREAT|O_RDWR);8     if(fd<0)9     {10         perror("open");11         return 1;12     }13     close(1);14     dup2(fd,1);15     for(;;)16     {17         char buf[1024]={0};18         ssize_t s=read(0,buf,sizeof(buf)-1);19         if(s<0)20         {21             perror("read");22             break;23         }24         printf("%s",buf);25         fflush(stdout);26     }27     return 0;28 }

运行结果:
这里写图片描述
打开文件./log我们可以看到,将输入的数据输出到了该文件中。