為同一個文件描述符創建兩個文件是否定義明確? (Is creating two FILEs for the same file descriptor well-defined?)


問題描述

為同一個文件描述符創建兩個文件是否定義明確? (Is creating two FILEs for the same file descriptor well‑defined?)

POSIX 指定了一個 fdopen 函數,該函數為一個文件描述符。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 使用 FILE 結構的固定表來存儲您可以打開的 20 個文件。因此,對已與 FILE 關聯的文件描述符調用 fdopen() 會破壞現有文件並產生未定義的行為。我不確定 POSIX 是否仍然允許 stdio 的這種實現,這就是我問這個問題的原因。


參考解法

方法 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.

(by fuzJohn BollingerThomas Padron‑McCarthy)

參考文件

  1. Is creating two FILEs for the same file descriptor well‑defined? (CC BY‑SA 2.5/3.0/4.0)

#file-descriptor #stdio #C #posix #language-lawyer






相關問題

在 Android 中持久化文件描述符 (Persisting File Descriptors in Android)

無法理解 select() 系統調用 (failure to understand select() system call)

文件描述符中實際存儲了多少信息? (How much information is actually stored in a file descriptor?)

為同一個文件描述符創建兩個文件是否定義明確? (Is creating two FILEs for the same file descriptor well-defined?)

Android文件描述符洩漏調試 (Android file descriptor leakage debuging)

C中的文件描述符分配 (File Descriptor Assignment in C)

在某些 linux 程序中關閉奇怪的描述符 (Strange descriptor closing in some linux programs)

c read() 導致錯誤的文件描述符錯誤 (c read() causing bad file descriptor error)

C中系統調用的文件句柄問題 (Filehandle issue with system call in C)

使用 copy_file_range 進行複制加速 (Copy acceleration with copy_file_range)

打開文件過多錯誤,但 99.5% 的 inode 是免費的 (Too many open files error but 99.5% inodes are free)

SIGPIPE 由於文件描述符和進程替換 (SIGPIPE due to file descriptors and process substitution)







留言討論