是否为明确定义的同一文件描述符创建了两个FILE?

时间:2015-11-16 12:50:59

标签: c posix language-lawyer file-descriptor stdio

POSIX指定fdopen函数,为文件描述符创建FILE。 POSIX还指定了fileno函数,该函数返回FILE的文件描述符。这两个可以一起用于创建第二个FILE访问与现有文件相同的基础文件描述符:

FILE *secondfile(FILE *f, const char *mode)
{
    int fd = fileno(f);

    return fd >= 0 ? fdopen(fd, mode) : NULL;
}

这是POSIX下定义明确的操作吗?当我同时访问为同一文件描述符创建的原始FILE和第二FILE时会发生什么?是否指定了交互?如果是,怎么样?

历史上,Unices为您打开的20个文件使用了FILE结构的固定表。因此,在已与fdopen()关联的文件描述符上调用FILE会破坏现有文件并产生未定义的行为。我不确定POSIX是否仍然允许stdio的这种实现,这就是我提出这个问题的原因。

2 个答案:

答案 0 :(得分:2)

POSIX Fiddle多个“句柄”与同一个底层“打开文件描述”同时关联,其中句柄可以是文件描述符或流。虽然它没有专门解决在同一文件描述符上通过fdopen()打开的多个流,但我认为没有理由认为这些要求比与相同的打开文件描述相关联的任何两个流更多或不同。受制于。

POSIX定义explicitly permits以避免未定义的行为。这里相关的是,对于作为文件描述符的句柄,这些约束确实很少;几乎所有这些都适用于流,它们主要围绕与缓冲相关的条件进行组织。例外情况与定位有关。

如果以与这些约束条件一致的方式使用流 - 大多数情况下(但不是唯一地),当您切换到使用另一个时,确保输出未在一个流中未被写入缓存 - 您可以期望流I / O函数表现为记录。否则,行为显式未定义。

答案 1 :(得分:1)

给定一个典型的Unix实现,使用包含要读取的文件描述符的FILE数据结构,以及用于缓冲的缓冲区,如果知道缓冲区的大小,以及填充它的策略(当需要数据,而不是在缓冲区为空时立即),我会说你可以确定会发生什么。但我不知道POSIX标准的含义,而且知道在程序中使用它将是一件困难的事情。 ("好的,所以我从磁盘上的文件读取前4096个字节到这个文件中,接下来的4096个字节读入那个文件,并且文件中的第三个4096字节块将被读入到首先到达其缓冲区末尾的FILE,并且需要阅读更多...")

(我从未故意做过这样的事情,但我似乎记得调试代码中的这些症状导致FILE和文件描述符混淆了。)

我的猜测将是POSIX没有足够好地指定它以保证它能够正常工作。例如,POSIX是否指定何时通过从文件描述符读取填充FILE中的缓冲区?当为空时,当空需要更多数据时,或其中任何一个,取决于什么?根据选择,文件描述符中的数据将显示在不同的文件中。