Is creating two FILEs for the same file descriptor well-defined?

旧巷老猫 提交于 2019-12-23 07:11:40

问题


POSIX specifies an fdopen function that creates a FILE for a file descriptor. POSIX also specifies a fileno function that returns the file descriptor for a FILE. Together, these two could be used to create a second FILE accessing the same underlying file descriptor as an existing file:

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

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

Is this a well-defined operation under POSIX? What happens when I access both the original FILE and the second FILE I made for the same file descriptor? Is the interaction specified? If yes, how?

Historically, Unices used a fixed table of FILE structures for the 20 files you could open. Calling fdopen() on a file descriptor that has already been associated with a FILE would thus corrupt the existing file and yield undefined behaviour. I am not sure if such an implementation of stdio is still allowed by POSIX, which is why I am asking this question.


回答1:


POSIX explicitly permits multiple "handles" to be associated simultaneously with the same underlying "open file description", where handles can be either file descriptors or streams. Although it does not specifically address multiple streams opened via fdopen() on the same file descriptor, I see no reason to suppose that these would be subject to more or different requirements than any two streams associated with the same open file description are generally subject to.

POSIX defines constraints on how two handles on the same open file description may be used in order to avoid undefined behavior. It is relevant here that those constraints are few indeed for handles that are file descriptors; almost all of them apply to streams, and they are organized mainly around conditions related to buffering. The exceptions are related to positioning.

If you use your streams in a manner consistent with those constraints -- mostly, but not exclusively, by ensuring that output is not buffered unwritten in one stream when you switch to using the other -- you can expect the stream I/O functions to behave as documented. Otherwise, the behavior is explicitly undefined.




回答2:


Given a typical Unix implementation, with a FILE data structure containing a file descriptor to read from, and a buffer for, eh, buffering, and if you know the size of the buffer, and the policy for filling it (when the data is needed, not immediately when the buffer is empty), I would say that you can determine what will happen. But I don't know what the POSIX standard says, and I do know that it will be a difficult thing to use in a program. ("Ok, so I've read the first 4096 bytes from the file on disk into this FILE, and the next 4096 bytes into that FILE, and the third 4096-byte chunk from the file will be read into the FILE that reaches the end of its buffer first and needs to read more...")

(I've never done anything like this deliberately, but I seem to remember such symptoms from debugging code that got FILEs and file descriptors mixed up.)

My guess would be that POSIX doesn't specify this well enough that it will be guaranteed to work. For example, does POSIX specify when a buffer inside a FILE will be filled by reading from the file descriptor? When empty, when empty and more data is needed, or either of these, depending on something? Depending on choice there, data from the file descriptor will show up in different FILEs.



来源:https://stackoverflow.com/questions/33735850/is-creating-two-files-for-the-same-file-descriptor-well-defined

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!