文件描述符的复制
Posted studying~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件描述符的复制相关的知识,希望对你有一定的参考价值。
文件描述符的复制
dup 和 dup2 是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup 和 dup2 经常用来重定向进程的 stdin、stdout 和 stderr。
回顾:ls > test.txt
包含头文件#include <unistd.h>
dup 函数介绍
int dup(int oldfd);
- 功能:复制 oldfd 文件描述符,并分配一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用 的文件描述符。
- 参数:要复制的文件描述符 oldfd。
- 返回值:成功:新文件描述符。 失败:返回-1,错误代码存于 errno 中。
dup2 函数介绍
int dup2(int oldfd, int newfd)
- 功能:复制一份打开的文件描述符 oldfd,并分配新的文件描述符 newfd,newfd 也标识 oldfd 所标识的文件。
- 注意:newfd 是小于文件描述符最大允许值的非负整数,如果 newfd 是一个已经打开的文件描述符,则会关闭该文件,然后再复制。
- 参数:要复制的文件描述符 oldfd 分配的新的文件描述符 newfd
- 返回值:成功:返回 newfd 失败:返回-1,错误代码存于 errno 中
案例1:dup实现printf输出重定向的功能
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
//如果需要实现输出重定向的功能
//首先像printf函数是操作文件描述符1所对应的文件,
//默认是操作终端,只要能够把1对应标识的文件改变,就可以实现输出重定向
//所以实现创建好文件对应的文件描述符之后,将1文件描述符关闭,接着通过dup
//函数复制的新的文件描述符就是1,这样printf函数对1操作,就写到了文件中
int fd_file;
fd_file = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if(fd_file == -1)
{
perror("fail to open");
exit(1);
}
close(1);
int fd = dup(fd_file);
printf("hello world\\n");
printf("fd = %d\\n", fd);
return 0;
}
执行结果:
案例2:dup实现输出重定向后,还想标准输出,如何实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd1;
int fd2;
fd2 = dup(1);
printf("new:fd2 = %d\\n",fd2);
fd1 = open("test.txt", O_RDWR | O_CREAT, 0664);
close(1);
int fd3 = dup(fd1);
printf("hello world\\n");
printf("fd = %d\\n", fd3);
close(1);
int fd4 = dup(fd2);
printf("nihao beijing\\n");
printf("fd = %d\\n", fd4);
return 0;
}
执行结果:
案例3:dup2实现printf输出重定向
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd1;
int fd2;
fd1 = open("test.txt", O_CREAT | O_WRONLY, 0664);
if (fd1 < 0)
{
perror("fail to open");
exit(1);
}
//首先关闭1文件描述符,然后将fd1复制给1,意味着1和fd1都标识test.txt文件,返回值跟1是一样的
fd2 = dup2(fd1, 1);
printf("hello world\\n");
printf("fd2 = %d\\n", fd2);
return 0;
}
执行结果:
案例4: dup2实现输出重定向后,再恢复标准输出
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd1;
//如果使用dup2,则需要实现给第二个参数对应的变量赋一个初始值
int fd2 = 3;
//将1复制一份为fd2,所以fd2标识的是标准输出
dup2(1, fd2);
printf("fd2 = %d\\n", fd2);
fd1 = open("test.txt", O_CREAT | O_RDWR, 0664);
//输出重定向:关闭文件描述符1,将fd1复制一份为1,所以1此时标识的是test.txt文件
dup2(fd1, 1);
printf("hello world\\n");
//再次实现标准输出:关闭文件描述符1,将fd2复制一份为1,所以1此时标识的是标准输出
dup2(fd2, 1);
printf("你好北京\\n");
return 0;
}
执行结果:
以上是关于文件描述符的复制的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 2010:调试时,如何从变量中复制包含回车符的字符串值?