1、要了解dup()、dup2()的使用先要了解文件描述符。文件描述符是非负整数,是文件的标识。用户使用文件描述符(file descriptor)来访问文件。
每个进程都有一张文件描述符的表,进程刚被创建时,标准输入、标准输出、标准错误输出设备文件被打开,对应的文件描述符0、1、2 记录在表中。在进程中打开其他文件时,系统会返回文件描述符表中最小可用的文件描述符,并将此文件描述符记录在表中。
Linux中一个进程最多只能打开NR_OPEN_DEFAULT(即1024)个文件,故当文件不再使用时应及时调用close函数关闭文件。
2、了解了文件描述符的概念,下面介绍函数:
dup和dup2是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。dup和dup2经常用来重定向进程的stdin、stdout和stderr。
1)int dup(int oldfd)
功能:
复制oldfd文件描述符,并分配一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符。
参数:要复制的文件描述符oldfd。
返回值:
成功:新文件描述符。
失败:返回-1,错误代码存于errno中。
2)int dup2(int oldfd, int newfd);
功能:
复制一份打开的文件描述符oldfd,并分配新的文件描述符newfd,newfd也标识oldfd所标识的文件。
注意:
newfd是小于文件描述符最大允许值的非负整数,如果newfd是一个已经打开的文件描述符,则首先关闭该文件,然后再复制。
3、下面是代码的测试、解析:
1)dup()
int main()
{
int fd1;
int fd2;
fd2=dup(1);//fd2也指向了stdout
printf("fd2=%d\n",fd2);//fd2=3,3为当前进程最小可用的,文件描述符,0、1、2被占用
fd1=open("test_dup",O_CREAT|O_RDWR,0777);
close(1);//1成为最小的可用的文件描述符
dup(fd1);//使新分配的文件描述符1也指向test文件
printf("hello world\n");//将输出到test文件中
close(1);//1成为最小的可用的文件描述符
dup(fd2);//使新分配的文件描述符1也指向stdout
printf("I am erlian\n");//将输出到stdout,默认屏幕
return 0;
}
2)dup2()
int main()
{
int fd1;
int fd2=3;
int err=0;
err=dup2(1,fd2);//fd2(3)也指向了stdout
if(err<0)
{
perror("dup2");
}
printf("fd2=%d,err=%d\n",fd2,err);
fd1=open("test_dup2",O_CREAT|O_RDWR,0777);
dup2(fd1,1);//关闭1指向stdout,使1指向fd1的指向,即test文件
printf("hello world\n");//输出到文件描述符1,即文件
dup2(fd2,1);//关闭1指向test,使1指向fd2的指向(stdout)
printf("I am erlian\n");//将输出到stdout,默认屏幕
return 0;
}