简体   繁体   English

使用 fdopen 的正确方法

[英]Correct way of using fdopen

I mean to associate a file descriptor with a file pointer and use that for writing.我的意思是将文件描述符与文件指针相关联并将其用于写入。 I put together program io.cc below:我把程序io.cc下面:

int main() {
    ssize_t nbytes;
    const int fd = 3;
    char c[100] = "Testing\n";
    nbytes = write(fd, (void *) c, strlen(c));     // Line #1
    FILE * fp = fdopen(fd, "a");
    fprintf(fp, "Writing to file descriptor %d\n", fd);
    cout << "Testing alternate writing to stdout and to another fd" << endl;
    fprintf(fp, "Writing again to file descriptor %d\n", fd);
    close(fd);     // Line #2
    return 0;
}

I can alternately comment lines 1 and/or 2, compile/run我可以交替注释第 1 行和/或第 2 行,编译/运行

./io 3> io_redirect.txt

and check the contents of io_redirect.txt .并检查io_redirect.txt的内容。 Whenever line 1 is not commented, it produces in io_redirect.txt the expected line Testing\n .只要第 1 行没有被注释,它就会在io_redirect.txt中产生预期的行Testing\n If line 2 is commented, I get the expected lines如果第 2 行被注释,我会得到预期的行

Writing to file descriptor 3
Writing again to file descriptor 3

in io_redirect.txt .io_redirect.txt中。 But if it is not commented, those lines do not show up in io_redirect.txt .但是如果没有注释,这些行就不会出现在io_redirect.txt中。

  • Why is that?这是为什么?
  • What is the correct way of using fdopen ?使用fdopen的正确方法是什么?

NOTE .注意 This seems to be the right approach for a (partial) answer to Smart-write to arbitrary file descriptor from C/C++ I say "partial" since I would be able to use C-style fprintf .这似乎是从 C/C++ 智能写入任意文件描述符的(部分)答案的正确方法我说“部分”,因为我可以使用 C 风格的fprintf I still would like to also use C++-style stream<< .我仍然想使用 C++ 风格的stream<<

EDIT : I was forgetting about fclose(fp) .编辑:我忘记了fclose(fp) That "closes" part of the question.这“关闭”了问题的一部分。

Why is that?这是为什么?

The opened stream ("stream" is an opened FILE* ) is block buffered, so nothing gets written to the destination before the file is flushed.打开的 stream (“流”是打开的FILE* )是块缓冲的,因此在刷新文件之前没有任何内容写入目标。 Exiting from an application closes all open streams , which flushes the stream .退出应用程序会关闭所有打开的流,从而刷新 stream

Because you close the underlying file descriptor before flushing the stream, the behavior of your program is undefined.因为在刷新 stream 之前关闭了底层文件描述符,所以程序的行为是未定义的。 I would really recommend you to read posix 2.5.1 Interaction of File Descriptors and Standard I/O Streams (which is written in a horrible language, nonetheless), from which:我真的建议您阅读posix 2.5.1 Interaction of File Descriptors and Standard I/O Streams (尽管它是用可怕的语言编写的),从中:

... if two or more handles are used, and any one of them is a stream, the application shall ensure that their actions are coordinated as described below. ...如果使用了两个或多个手柄,并且其中任何一个是 stream,应用程序应确保它们的动作按如下所述进行协调。 If this is not done, the result is undefined.如果不这样做,结果是未定义的。

... ...

For the first handle, the first applicable condition below applies.对于第一个手柄,适用以下第一个适用条件。 ... ...

  • ... ...

  • If it is a stream which is open for writing or appending (but not also open for reading), the application shall either perform an fflush(), or the stream shall be closed.如果它是一个 stream,它对写入或附加打开(但也不是对读取打开),应用程序要么执行 fflush(),要么关闭 stream。

A "handle" is a file descriptor or a stream. “句柄”是文件描述符或 stream。 An "active handle" is the last handle that you did something with. “活动句柄”是您使用的最后一个句柄。

The fp stream is the active handle that is open for appending to file descriptor 3 . fp stream 是打开以附加到文件描述符3的活动句柄。 Because fp is an active handle and is not flushed and you switch the active handle to fd with close(fd) , the behavior of your program is undefined.因为fp是一个活动句柄并且没有刷新,并且您使用close(fd)将活动句柄切换到fd ,所以您的程序的行为是未定义的。

What is my guess and most probably happens is that your C standard library implementation calls fflush(fp) after main returns, because fd is closed, some internal write(3, ...) call returns an error and nothing is written to the output.我的猜测是什么,最有可能发生的是您的 C 标准库实现在main返回后调用fflush(fp) ,因为fd已关闭,某些内部write(3, ...)调用返回错误并且没有任何内容写入 output .

What is the correct way of using fdopen?使用 fdopen 的正确方法是什么?

The usage you presented is the correct way of using fdopen .您提出的用法是使用fdopen的正确方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM