题目咋看上去不好写,其实只要理解了dup函数和dup2函数的功能以及他们参数的限制,可以很快想到使用dup函数实现dup2函数。
先来说下dup函数,他是复制一个文件描述符,而复制的文件描述符的值为当前系统未被使用的文件描述符的最小值。成功返回复制的文件描述符,失败返回-1。
再来看下dup2函数,他同样复制一个文件描述符,但由用户指定要复制的文件描述符的值(即函数的第二个参数fd2),首先要明确fd2为0时,此时dup2等于dup。
如果fd2与dup2函数的第一个参数(即fd)相同,则直接返回即可。比较难的地方是,当fd2不等于fd时,且fd2不等于0,此时我们要先关闭fd2,如果fd2已经被打开,则close执行成功,此时,系统未被使用的文件描述符的最小值就变成了fd2,此时调用dup的返回值肯定为fd2。如果fd2没有被打开,close调用失败,那我们就一直调用dup,直到dup的返回值为fd2,此时就完成了复制文件描述符的工作了,再把之前dup打开的文件描述符关闭即可(保存一个数组中)。
下面是完整代码
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int mydup2(int fd,int fd2)
{
int fds[256];
int t = -1;
int i = 0;
if (fd2 < 0 || fd2 > 256)
{
printf("fd2 must more than 0 and less than 256\n");
return -1;
}
if (fd2 == 0)
return dup(fd);
if (fd == fd2)
return fd;
else
{
if ( close(fd2) == 0)
{
return dup(fd);
}
else
{
while(t != fd2)
{
t = dup(fd);
fds[i] = t;
++i;
}
t = i - 1;
for(i = 0;i < t;++i)
close(fds[i]);
return fd[t-1];
}
}
}
int main(int argv,char **args)
{
if (argv != 3)
{
printf("useage:three args!\n");
return -1;
}
int fd = atoi(args[1]);
int fd2 = atoi(args[2]);
int t = mydup2(fd,fd2);
printf("%d\n",t);
return 0;
}