linux c dup2 函数解析
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
//打开一个文件
int fd = open("./log", O_CREAT | O_RDWR, 0644);
if(fd < 0)
{
perror("open");
return 1;
}
printf("int dup2(int oldfd, int newfd);\n");
printf("fd =%d\n",fd);
//关闭标准输出文件描述符
// close(1); //dup2不需要手动关闭,系统会自动关闭
//进行重定向
int new_fd = dup2(fd, 1); //new_fd = 1
fprintf(stderr,"int new_fd = dup2(fd, 1);\n");
fprintf(stderr,"new_fd = %d\n",new_fd);
if(new_fd < 0)
{
perror("dup2");
return 2;
}
close(fd);
char buf[1024];
while(1)
{
memset(buf, '\0', sizeof(buf));
ssize_t _s = read(0, buf, sizeof(buf) - 1);
if(_s < 0)
{
perror("read");
return 3;
}
else
{
buf[_s] = '\0';
}
if(strncmp("quit", buf, 4) == 0)
{
//退出
break;
}
printf("%s", buf); //将往文件中写入
fflush(stdout); //必须做,因为重定向后printf函数将由行缓冲变为全缓冲
sleep(1);
}
close(new_fd);
return 0;
}
输出内容
int dup2(int oldfd, int newfd);
fd =3
int new_fd = dup2(fd, 1);
new_fd = 1
fd 是打开的 log文件的句柄
通过 dup2(fd, 1); 函数关闭原来的 句柄为1的文件,然后将打开的 log文件的句柄 ,由3设置为1.
这样printf等函数往句柄为1的文件里面写输入。
现在句柄为1的文件变成打开的 log文件了。
阳光幼儿园 门牌号是 123
阳光幼儿园对面开了一家苗苗照相馆 门牌号 是235
有人给 阳光幼儿园 发快递,地址是 门牌号123
有一天
照相馆把自己的门牌号 235牌子摘掉,把阳光幼儿园的门牌号 123牌子,放在自己得的门牌号位置上。
快递员,就会把原本发送给阳光幼儿园 的快递 送到 照相馆。
man dup2
int dup2(int oldfd, int newfd);
dup2()
The dup2() system call performs the same task as dup(), but instead of using the lowest-numbered unused file descriptor, it uses the descriptor
number specified in newfd. If the descriptor newfd was previously open, it is silently closed before being reused.
The steps of closing and reusing the file descriptor newfd are performed atomically. This is important, because trying to implement equivalent
functionality using close(2) and dup() would be subject to race conditions, whereby newfd might be reused between the two steps. Such reuse could
happen because the main program is interrupted by a signal handler that allocates a file descriptor, or because a parallel thread allocates a file
descriptor.
Note the following points:
* If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.