文件描述符: 每个进程对应一个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
int dup(int oldfd);
int dup2(int oldfd,int newfd)
dup把标准输出重定向至文件中
#include
#include
#include
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
",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
#include
#include
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);