有人能解释一下 C 中的 dup() 的作用吗?

发布于 2024-12-11 22:23:22 字数 383 浏览 0 评论 0原文

我知道 dup、dup2、dup3“创建文件描述符 oldfd 的副本”(来自手册页)。然而我无法消化它。

据我所知,文件描述符只是数字,用于跟踪文件位置及其方向(输入/输出)。 这不是更容易吗

fd=fd2;

每当我们想要复制文件描述符时,

?还有别的东西..

dup() 使用编号最小的未使用描述符作为新描述符。

这是否意味着它也可以将 stdinstdoutstderr 如果我们假设我们已经 close()-ed 其中之一?

I know that dup, dup2, dup3 "create a copy of the file descriptor oldfd"(from man pages). However I can't digest it.

As I know file descriptors are just numbers to keep track of file locations and their direction(input/output). Wouldn't it be easier to just

fd=fd2;

Whenever we want to duplicate a file descriptor?

And something else..

dup() uses the lowest-numbered unused descriptor for the new descriptor.

Does that mean that it can also take as value stdin, stdout or stderr if we assume that we have close()-ed one of those?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

恏ㄋ傷疤忘ㄋ疼 2024-12-18 22:23:23

dup() 最重要的一点是它返回新文件描述符可用的最小整数。这就是重定向的基础:

int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */

写入文件描述符 1(stdout)的任何内容都会神奇地进入“文件”。

The single most important thing about dup() is it returns the smallest integer available for a new file descriptor. That's the basis of redirection:

int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */

After this anything written to file descriptor 1 (stdout), magically goes into "file".

放血 2024-12-18 22:23:23

假设您正在编写一个 shell 程序,并且想要在要运行的程序中重定向 stdin 和 stdout。它可能看起来像这样:

fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
    close(0);
    dup(fdin);
    close(fdin);
    close(1);
    dup(fdout);
    close(fdout);
    execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...

dup2() 是一种更方便的方法 close() dup() 可以替换为:

dup2(fdin, 0);
dup2(fdout, 1);

你想要这样做的原因是你想向 stdout 报告错误(或stderr) 因此您不能只是关闭它们并在子进程中打开一个新文件。其次,如果任何一个 open() 调用返回错误,那么执行 fork 将是一种浪费。

Let's say you're writing a shell program and you want to redirect stdin and stdout in a program you want to run. It could look something like this:

fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
    close(0);
    dup(fdin);
    close(fdin);
    close(1);
    dup(fdout);
    close(fdout);
    execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...

dup2() is a little more convenient way to do it the close() dup() can be replaced by:

dup2(fdin, 0);
dup2(fdout, 1);

The reason why you want to do this is that you want to report errors to stdout (or stderr) so you can't just close them and open a new file in the child process. Secondly, it would be a waste to do the fork if either open() call returned an error.

暗藏城府 2024-12-18 22:23:23

示例:

<前><代码>关闭(1); //关闭标准输出
newfd=dup(1); //newfd 取最少可用 fd 编号的值

文件描述符发生这种情况的地方:

0 标准输入.--------------。 0 标准输入.--------------。 0 标准输入
1 个标准输出 =|关闭(1) :=> 2 标准错误 =| newfd=dup(1) :=> 1 新FD
2 标准错误 '--------------' '--------------' 2 标准错误

又出现了一个问题:如何dup()一个我已经关闭的文件描述符?

我怀疑您是否使用显示的结果进行了上述实验,因为这不符合标准 - 参见。 dup

在以下情况下,dup() 函数将失败:

[EBADF]
fildes 参数不是有效的打开文件描述符。

因此,在显示的代码序列之后,newfd 必须不是 1,而是 -1,并且 errno <代码>EBADF。

Example:

close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number

Where this happens to file descriptors:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr

A question arose again: How can I dup() a file descriptor that I already closed?

I doubt that you conducted the above experiment with the shown result, because that would not be standard-conforming - cf. dup:

The dup() function shall fail if:

[EBADF]
The fildes argument is not a valid open file descriptor.

So, after the shown code sequence, newfd must be not 1, but rather -1, and errno EBADF.

苦行僧 2024-12-18 22:23:23

请参阅此页面,stdout 可以别名为 dup(1)< /代码>...

see this page, stdout can be aliased as dup(1)...

·深蓝 2024-12-18 22:23:23

只是关于“复制标准输出”的提示。

在某些 Unix 系统(但不是 GNU/Linux)上,

fd = open("/dev/fd/1", O_WRONLY);

它相当于:

fd = dup(1);

Just a tip about "duplicating standard output".

On some Unix Systems (but not GNU/Linux)

fd = open("/dev/fd/1", O_WRONLY);

it is equivalent to:

fd = dup(1);
眼睛会笑 2024-12-18 22:23:23

dup() 和 dup2() 系统调用

• dup() 系统调用复制打开的文件描述符并返回新文件
描述符。

•新的文件描述符具有以下共同属性
原来的
文件描述符:
1. 指同一个打开的文件或管道。
2. 具有相同的文件指针——即两个文件描述符共享一个文件指针。
3.具有相同的访问模式,无论是读、写还是读写。

• dup() 保证返回可用的最低整数值的文件描述符。正是由于返回可用的最低未使用文件描述符的这一特性,进程才能完成 I/O 重定向。

int dup(文件描述符)

int dup2(文件描述符1, 文件描述符2)

dup() and dup2() system call

•The dup() system call duplicates an open file descriptor and returns the new file
descriptor.

•The new file descriptor has the following properties in common with
the original
file descriptor:
1. refers to the same open file or pipe.
2. has the same file pointer -- that is, both file descriptors share one file pointer.
3. has the same access mode, whether read, write, or read and write.

• dup() is guaranteed to return a file descriptor with the lowest integer value available.It is because of this feature of returning the lowest unused file descriptor available that processes accomplish I/O redirection.

int dup(file_descriptor)

int dup2(file_descriptor1, file_descriptor2)

养猫人 2024-12-18 22:23:22

只是想在尝试了一下之后回答我自己的第二个问题。

答案是。如果 stdin、stdout 或 stderr 关闭,则您创建的文件描述符可以采用值 0、1、2。

示例:

close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number

文件描述符发生这种情况的情况:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr

Just wanted to respond to myself on the second question after experimenting a bit.

The answer is YES. A file descriptor that you make can take a value 0, 1, 2 if stdin, stdout or stderr are closed.

Example:

close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number

Where this happens to file descriptors:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr
关于从前 2024-12-18 22:23:22

文件描述符不仅仅是一个数字。它还带有各种半隐藏状态(无论它是否打开,它引用哪个文件描述,以及一些标志)。 dup 复制此信息,因此您可以独立关闭两个描述符。 fd=fd2 没有。

A file descriptor is a bit more than a number. It also carries various semi-hidden state with it (whether it's open or not, to which file description it refers, and also some flags). dup duplicates this information, so you can e.g. close the two descriptors independently. fd=fd2 does not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文