这是unix编程环境第三章的一个题目,前段时间翻了下,发现这个题目还有点小意思,而且网上也没什么全面的答案。
先补充几个概念:
文件描述符:内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。(百度百科)
内核为每个进程维护一张进程表项,每一行代表一个打开的文件,包含两个数据:文件描述符、指向文件表的指针。进程为每个打开的文件维护一张文件表,文件表记录了文件一些基本信息,以及指向文件实体的指针,大体如下图:
当我们打开一个文件的时候,内核会返回一个对应的文件描述符(通常从3开始递增,0、1、2分别代表STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO);
int dup(int fd);
复制fd描述符,并且是当前可用的最小描述符
int dup2(int fd1,int fd2);
复制fd1的描述符,并且其值为fd2
题目要做的就是实现dup2,但不能调用fcntl函数
代码如下
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- int mydup2(int filedes, int filedes2);
- int main(void)
- {
- int a,b;
- a = open("1.txt", O_RDWR);
- b = mydup2(a,1);
- write(b,"tsslssdfesaat",20);
- }
- int mydup2(int filedes, int filedes2)
- {
- int filetmp, i = 0;
- int filearr[filedes2];
- //测试filedes是否合法
- filetmp = dup(filedes);
- if(filetmp == -1)
- {
- return -1;
- }else
- {
- close(filetmp);
- }
- if(filedes == filedes2)
- {
- return filedes;
- }else
- {
- //关闭filedes
- close(filedes);
- for(i = 0; i < filedes2 + 1; i++)
- {
- filearr[i] = 0;
- filetmp = dup(filedes);
- if(filetmp < 0)
- {
- return -1;
- }else
- {
- if(filetmp == filedes2)
- break;
- else
- filearr[filetmp] = 1;
- }
- }
- }
- for(i = 0; i < filedes2; i++)
- {
- if(filearr[i] == 1)
- close(i);
- }
- return filetmp;
- }