函数原型
int dup(int fd);
int dup2(int fd, int fd2);
int mydup2(int fd, int fd2);
由于题目要求不能使用fcntl函数,所以考虑使用dup函数来实现,思路如下:
- 首先对于参数fd2,应当大于等于当前未使用的最小文件描述符,那么如何确定这个最小值呢?想到dup函数的返回值就是dup函数被调用前最小的未使用的文件描述符,设它为fd_min。
- 如果fd2大于fd_min,只要使从fd_min到fd2这个区间内(不包含fd2)未使用的文件描述符都被占用,那么只要再调用一次函数dup(fd),那么返回值就等于fd2了。
- 然后考虑如何使区间内未被使用的文件描述符被占用,只要不断调用dup(fd)直到返回值等于fd2即可,之后再将区间内除fd2之外的那些被设置过的文件描述符逐个关闭,这时候我们就成功将fd复制给了fd2.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int mydup2(int fd, int fd2)
{
int fd_min, index, n, t, *fdarr;
if((fd_min = dup(fd)) < 0){
perror("error when dup");
return -1;
}
if(fd_min == fd2)
return fd_min;
if(fd_min > fd2){
perror("fd2 has being used");
return -1;
}
n = fd2 - fd_min + 1;
fdarr = (int *)malloc(n * sizeof(int));
fdarr[0] = fd_min;
index = 1;
while(index < n){
if((fdarr[index] = dup(fd)) < 0){
perror("error when dup");
return -1;
}
if(fdarr[index] == fd2){
for(int i = 0; i <= index - 1; i++)
close(fdarr[i]);
t = fdarr[index];
free(fdarr);
return t;
}
index++;
}
perror("error when loop");
return -1;
}
int main()
{
int fd = 0;
if((fd = mydup2(0, 5)) < 0){
printf("error when mydup2!\n");
exit(0);
}
printf("fd = %d\n", fd);
}