1. 程式人生 > >dup和dup2之理解

dup和dup2之理解

檔案描述符:                                                                                                                                                                                      每個程序對應一個PCB,一個PCB對應一份檔案描述符,檔案描述符裡有檔案,每個檔案對應一個檔案結構體,檔案結構體有陣列陣列下標為檔案描述符,每個檔案描述符對應一個file結構體,file結構體有讀寫許可權,讀寫位置,引用計數,f_op。f_op指向一個操作檔案的API結構體file_operations(read/write...)                                                                                                                         PCB(file)---file(files_struct)---files_struct(fd_array[fd])--fd_array[fd](files)---files(許可權,f_entry入口,引用計數,f_op)---f_op(file_operations)---file_operations(read,write)

示意圖:

dup和 dup2函式原型:系統呼叫

#include<unistd.h>
int dup(int oldfd);
int dup2(int oldfd,int newfd)

dup把標準輸出重定向至檔案中

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{
	int fd = open("./log", O_CREAT | O_RDWR);
	if (fd < 0)
	{
		perror("open failed");
		return 1;
	}
	close(1);      
	int new_fd = dup(fd);
	if (new_fd != 1)
	{
		perror("dup failed");
		return 1;
	}
	printf("new_fd: %d\n",new_fd);
	close(fd);
	for (;;)
	{
		char buf[1024] = {0};
		ssize_t read_size = read(0, buf, sizeof(buf)-1);
		if (read_size < 0)
		{
			perror("read");
			continue;
		}
		printf("%s",buf);
		fflush(stdout);
	}
	close(new_fd);
	return 0;
}

解惑:1.0 dup之前close(1)  1標準輸出  dup原理:建立一個可用的最小的檔案描述符open中厚的返回值為3 如果不close(1)

            此處的new_fd一定為4

           2.0 fflush的必要:每次讀完都需要重新整理緩衝區不然資料還在緩衝區而不能重定向到檔案裡。

           3.0 dup等價於fcntl(oldfd,F_DUPFD,0);

dup2把標準輸出重定向至檔案中

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{
	int fd = open("./log", O_CREAT | O_RDWR);
	if (fd < 0)
	{
		perror("open failed");
		return 1;
	}
	close(1);
	dup2(fd,1);
	for (;;)
	{
		char buf[1024] = {0};
		ssize_t read_size = read(0, buf, sizeof(buf)-1);
		if (read_size < 0)
		{
			perror("read");
			continue;
		}
		printf("%s",buf);
		fflush(stdout);
	}
	return 0;
}

解惑:1.0 直接將檔案描述符重定向不用判斷將new_fd重定向為old_fd

           2.0 沒有close(old_fd) 內建在dup2裡了

           3.0 dup2等價於close(old_fd);fcntl(old_fd,FDUPFD,new_fd);