pie*_*fou 63 c unix file system-calls dup
我知道是什么dup/dup2做什么,但我不知道什么时候会被使用.
任何实际的例子?
谢谢.
Alf*_*nso 62
一个示例用途是I/O重定向.为此你分叉一个子进程并关闭stdin或stdout文件描述符(0和1)然后你在你选择的另一个filedescriptor上做一个dup(),它现在将被映射到最低的可用文件描述符,这是在这里案例0或1.
使用它,您现在可以执行任何可能不知道您的应用程序的子进程,并且只要子进程在stdout上写入(或从stdin读取,无论您配置什么),数据都会写在提供的文件描述符上.
Shell使用它来实现带管道的命令,例如/bin/ls | more通过将一个进程的stdout连接到另一个进程的stdin.
Zij*_*ost 23
理解dup和dup2的最佳方案是重定向.
首先我们需要知道的是系统有3个默认文件id(或指示输出或输入源的变量)来处理输入和输出.它们是stdin,stdout,stderr,在整数它们是0,1,2.大多数函数喜欢fprintf或cout直接输出到stdout.
如果我们想重定向输出,一种方法是,例如,fprintf函数更多的参数指示in和out.
但是,有一种更优雅的方式:我们可以覆盖默认文件ID,使它们指向我们想要接收输出的文件.dup并dup2准确地在这种情况下工作.
现在让我们从一个简单的例子开始:假设我们想要将输出重定向fprintf到名为"chinaisbetter.txt"的txt文件.首先,我们需要打开这个文件
int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);
Run Code Online (Sandbox Code Playgroud)
然后我们想stdout通过使用dup函数指向"chinaisbetter.txt":
dup2(fw,1);
Run Code Online (Sandbox Code Playgroud)
现在stdout(1)指向"chinaisbetter.txt"的描述符,即使它仍然是1,但输出现在被重定向.
然后您可以printf正常使用,但结果将在txt文件中,而不是直接显示在屏幕上:
printf("Are you kidding me? \n");
Run Code Online (Sandbox Code Playgroud)
PS:
这只是一个直观的解释,您可能需要检查手册页或详细信息.实际上,我们在这里说"复制",他们并没有复制一切.
这里的文件ID是指文件的处理程序.上面提到的文件描述符是记录文件信息的结构.
Tim*_*ost 10
当您对POSIX函数感到好奇时,特别是那些似乎自己复制的函数,通常检查标准本身是件好事.在底部,您通常会看到示例,以及两者的实现(和存在)背后的推理.
在这种情况下:
以下部分内容丰富.
将标准输出重定向到文件
以下示例关闭当前进程的标准输出,重新分配标准输出以转到引用的文件pfd,并关闭原始文件描述符以进行清理.
#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...
Run Code Online (Sandbox Code Playgroud)
以下示例将消息重定向stderr到stdout.
#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...
Run Code Online (Sandbox Code Playgroud)
没有.
这些dup()和dup2()功能是多余的.他们的服务也由该fcntl()功能提供.它们已被包含在IEEE Std 1003.1-2001的这一卷中,主要是出于历史原因,因为许多现有应用程序使用它们.
虽然所示的简短代码段的行为非常相似,但dup2()基于本卷IEEE Std 1003.1-2001中定义的其他功能的一致实现要复杂得多.最明显的是信号捕获函数的可能影响,可以在步骤之间调用并分配或取消分配文件描述符.阻止信号可以避免这种情况.
该dup2()功能未标记为过时,因为它提供了类型不安全版本中提供的类型安全版本的功能fcntl().它用于POSIX Ada绑定.
该dup2()功能不适用于关键区域作为同步机制.
在[EBADF]的描述中,fildes超出范围的情况由fildes无效的给定情况涵盖.对fildes和的描述fildes2是不同的,因为唯一的无效性fildes2是否超出范围; 也就是说,fildes2在进行dup2()调用时是否引用打开的文件并不重要.
没有.
close(),fcntl(),open(),IEEE标准1003.1-2001的基本定义体积,<unistd.h>
首次发布在第1期中.来自SVID的第1期.
一个实际的例子是将输出消息重定向到某些其他流,如某些日志文件.以下是I/O重定向的示例代码.
请在这里参考原帖
#include <stdio.h>
main()
{
int fd;
fpos_t pos;
printf("stdout, ");
fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen("stdout.out", "w", stdout);
f();
fflush(stdout);
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos); /* for C9X */
printf("stdout again\n");
}
f()
{
printf("stdout in f()");
}
Run Code Online (Sandbox Code Playgroud)