头文件:unistd.h
原型如下:
int dup(int oldfd)
int dup(int oldfd)
int dup2(int oldfd,int newfd)
描述:
系统调用dup和dup2能够复制oldfd文件描述符。dup返回新的文件描述符(使用最小的没有使用的文件描述符编号)。
dup2创建一个新的文件描述符newfd,这个描述符是复制oldfd得来。可以让用户指定返回的文件描述符的值(newfd),注意以下两点:
a)如果oldfd不是一个有效的文件描述符,这时调用失败,newfd不会被关闭
b)如果oldfd是一个有效的文件描述符,newfd值跟它相同,这时dup2什么也不做,返回newfd。
他通常用来重新打开或者重定向一个文件描述符。
dup2创建一个新的文件描述符newfd,这个描述符是复制oldfd得来。可以让用户指定返回的文件描述符的值(newfd),注意以下两点:
a)如果oldfd不是一个有效的文件描述符,这时调用失败,newfd不会被关闭
b)如果oldfd是一个有效的文件描述符,newfd值跟它相同,这时dup2什么也不做,返回newfd。
他通常用来重新打开或者重定向一个文件描述符。
返回值:
如果成功,dup 和dup2都是返回新的描述符。或者返回-1并设置 errno变量
其他:
要提到这个头文件unistd.h同时定义了下面三个常量:
STDERR_FILENO = 2 标准错误输出
STDIN_FILENO = 0 标准输入
STDOUT_FILENO = 1 标准输出
其他:
要提到这个头文件unistd.h同时定义了下面三个常量:
STDERR_FILENO = 2 标准错误输出
STDIN_FILENO = 0 标准输入
STDOUT_FILENO = 1 标准输出
示例:
1)
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int fd,fd2,fd3;
char buf[] = "Hello, world!";
char buf2[50] = {0};
if((fd=open("/home/****/Desktop/myTest/CTest/pipe/helloworld",O_CREAT|O_TRUNC|O_RDWR,0666))==-1)//"****"表示linux系统的用户名
{
printf("Open or create file named \"helloworld\" failed.\n");
exit(1);
}
printf("first fd = %d\n",fd);
write(fd,buf,sizeof(buf));
close(fd);
if((fd=open("/home/****/Desktop/myTest/CTest/pipe/helloworld",O_RDONLY))==-1)
{
printf("Open file named \"helloworld\" failed.\n");
exit(1);
}
printf("seconed fd = %d\n",fd);
fd2=dup(fd);
fd3=dup2(fd,8);
printf("fd2 = %d\n",fd2);
printf("fd3 = %d\n",fd3);
read(fd3,buf2,sizeof(buf2));
printf("buf2 : %s\n",buf2);
close(fd);
close(fd2);
close(fd3);
return 0;
}
输出结果:
first fd = 3
second fd = 3
fd2 = 4
fd3 = 8
buf2 : Hello, world!
2)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int old;
FILE *new;
old = dup(STDOUT_FILENO); /* "old" now refers to "stdout" */
/* Note: file handle 1 == "stdout" ,0 == "stdin",2 == "stderr"*/
if(old == -1)
{
perror("dup(STDOUT_FILENO) failure");
exit(1);
}
write(old, "This goes to stdout first\r\n", 27 );
if(NULL == (new = fopen( "data", "w" )) )
{
puts( "Can't open file 'data'\n" );
exit( 1 );
}
/* stdout now refers to file "data" */
if( -1 == dup2( fileno( new ),STDOUT_FILENO ) )
{
perror( "Can't dup2 stdout" );
exit( 1 );
}
/* write this info to 'data'*/
puts("aaa");
puts( "This goes to file 'data'\r" );
puts("bbb");
/* Flush stdout stream buffer so it goes to correct file */
fflush(stdout);
fclose(new);
/* Restore original stdout */
dup2( old, STDOUT_FILENO );
puts( "This goes to stdout" );
puts( "The file 'data' contains:" );
system( "ls -l" );
return 0;
}
输出结果:
This goes to stdout first
total 56
-rw-r--r-- 1 *** 35 2014-11-13 18:53 data
-rw-r--r-- 1 *** 1068 2014-11-13 18:53 test_dup2.c
-rw-r--r-- 1 *** 881 2014-11-13 18:53 test_dup.c
This goes to stdout
The file 'data' contains:
其中红色的打印内容,是在终端执行“ls -l”执行的显示结果。
在该目录下同时声称“data”文件,内容:
aaa
This goes to file 'data'
bbb
3)dup2与管道结合
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int fd,fd2,fd3;
char buf[] = "Hello, world!";
char buf2[50] = {0};
if((fd=open("/home/****/Desktop/myTest/CTest/pipe/helloworld",O_CREAT|O_TRUNC|O_RDWR,0666))==-1)//"****"表示linux系统的用户名
{
printf("Open or create file named \"helloworld\" failed.\n");
exit(1);
}
printf("first fd = %d\n",fd);
write(fd,buf,sizeof(buf));
close(fd);
if((fd=open("/home/****/Desktop/myTest/CTest/pipe/helloworld",O_RDONLY))==-1)
{
printf("Open file named \"helloworld\" failed.\n");
exit(1);
}
printf("seconed fd = %d\n",fd);
fd2=dup(fd);
fd3=dup2(fd,8);
printf("fd2 = %d\n",fd2);
printf("fd3 = %d\n",fd3);
read(fd3,buf2,sizeof(buf2));
printf("buf2 : %s\n",buf2);
close(fd);
close(fd2);
close(fd3);
return 0;
}
输出结果:
first fd = 3
second fd = 3
fd2 = 4
fd3 = 8
buf2 : Hello, world!
2)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int old;
FILE *new;
old = dup(STDOUT_FILENO); /* "old" now refers to "stdout" */
/* Note: file handle 1 == "stdout" ,0 == "stdin",2 == "stderr"*/
if(old == -1)
{
perror("dup(STDOUT_FILENO) failure");
exit(1);
}
write(old, "This goes to stdout first\r\n", 27 );
if(NULL == (new = fopen( "data", "w" )) )
{
puts( "Can't open file 'data'\n" );
exit( 1 );
}
/* stdout now refers to file "data" */
if( -1 == dup2( fileno( new ),STDOUT_FILENO ) )
{
perror( "Can't dup2 stdout" );
exit( 1 );
}
/* write this info to 'data'*/
puts("aaa");
puts( "This goes to file 'data'\r" );
puts("bbb");
/* Flush stdout stream buffer so it goes to correct file */
fflush(stdout);
fclose(new);
/* Restore original stdout */
dup2( old, STDOUT_FILENO );
puts( "This goes to stdout" );
puts( "The file 'data' contains:" );
system( "ls -l" );
return 0;
}
输出结果:
This goes to stdout first
total 56
-rw-r--r-- 1 *** 35 2014-11-13 18:53 data
-rw-r--r-- 1 *** 1068 2014-11-13 18:53 test_dup2.c
-rw-r--r-- 1 *** 881 2014-11-13 18:53 test_dup.c
This goes to stdout
The file 'data' contains:
其中红色的打印内容,是在终端执行“ls -l”执行的显示结果。
在该目录下同时声称“data”文件,内容:
aaa
This goes to file 'data'
bbb
3)dup2与管道结合