實現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);
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章