实现dup2功能相同的函数

自行实现dup2的功能。函数原型:int mydup2(int fd, int fd2),思路如下:

1.fd2小于0,直接返回错误;

2.如果fd是有效的文件描述符且等于fd2,直接返回fd2;

3.如果fd2已经打开,关闭fd2;

4.分配一个长度为fd2值的fdset数组,不断调用dup,直到返回的文件描述符的值和fd2相等;

5.清理资源,返回fd2。


实现的函数代码如下:

#include<stdio.h>
#include<errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<string.h>
int mydup2(int fd, int fd2) {
	if (fd2 < 0) {
		printf("fd2 can not under zero!\n");
		return -1;
	}
	int tempfd = dup(fd);//判断fd是否是打开的文件描述符
	if (tempfd == -1) {
		printf("dup(fd) %d, error : %s\n", __LINE__, strerror(errno));
		return -1;
	}
	if (fd == fd2) {//fd是已经有效文件描述符,如果和fd2相同,直接返回
		return fd2;
	}
	tempfd = dup(fd2);
	if (tempfd == -1) { //fd2可能是沒有打開,也可能是其他原因(man dup查看)
		//ignore
	} else { //关闭fd2
		close(fd2);
		close(tempfd);
	}
	int *fdset = malloc(fd2 * sizeof(int));
	int i = 0;
	int success = 0;
	for (i = 0; i < fd2; i++) {//一般描述符不要写太大,这里不做优化。
		if (success == 0) {//如果还没打开到fd2
			tempfd = dup(fd);
		} else {//如果fd2已经打开了
			fdset[i] = 0;
			continue;
		}
		if (tempfd == -1) {
			printf("dup(fd) %d, error : %s\n", __LINE__, strerror(errno));
			free(fdset);
			return -1;
		} else if (tempfd == fd2) {
			success = 1;
		} else {
			fdset[i] = tempfd;
		}
	}
	for (i = 0; i < fd2; i++) {
		if (fdset[i] != 0) {
			close(fdset[i]);
		}
	}
	if (success == 0) {
		free(fdset);
		printf("my_dup2, %d] error : %s\n", __LINE__, strerror(errno));
		return -1;
	}
	free(fdset);
	return fd2;
}

测试代码如下,如果mydup2能成功运行,那么必定会产生文件mydup2file.txt:

int main(int argc, char **argv) {
	if (argc != 2) {
		printf("usege: ./mydup2 <newfd>\n");
		exit(1);
	}
	umask(0);
	int j = 0;
	int fd = 0;
	for (;j<10;j++) {
		 fd = open("/home/lhm/桌面/mydup2file.txt", O_CREAT|O_RDWR, S_IRWXU|S_IRWXG);
	}
	int fd2 = atoi(argv[1]);
	if (mydup2(fd, fd2) == -1 ) {
		printf("mydup2, %d] error : %s\n", __LINE__, strerror(errno));
		exit(1);
	}
	char *sucMsg = "hello, mydup2 fun success!";
	if (write(fd2, sucMsg, 26) != 26) {
		printf("error, 一次性無法全部寫入內容!(爲了儘量簡化,不會處理這個問題)\n");
	}
	close(fd);
	close(fd2);
	printf("執行成功!\n");
	exit(0);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值