Shell
shell/init 如何創建 stdio 流?
我正在閱讀 MIT’s xv6 OS的原始碼。這個片段出現在開頭
sh.c
:// Ensure that three file descriptors are open. while((fd = open("console", O_RDWR)) >= 0){ if(fd >= 3){ close(fd); break; } }
我知道這通過檢查新分配的文件描述符是否高於(或等於)3來檢查是否打開了至少3個文件描述符(可能是stdin、stdout和stderr)。
1)如何
open
從同一個程序多次訪問同一個設備並期望不同的文件描述符?2)為了理解這一點,我在我的主機(x86_64 Linux 4.6.0.1)上執行了一個類似的片段。測試程序
open
在循環中重複編輯一個文本文件,看看我們是否可以期待不同的 fd,但它總是產生相同的文件描述符。由此,我得出結論,open
-ing 一個真實的文件和一個設備(如/dev/console
)在某種程度上有所不同,因為來自 xv6 的片段顯然有效(在 Qemu 中測試)。究竟有什麼區別?#include <stdlib.h> #include <fcntl.h> #include <stdio.h> int main(void) { int fd; int cnt = 0; while ((fd = open("sample.txt", O_RDWR) > 0)) { if (cnt != 10) { cnt++; printf("File descriptor opened: %d\n", fd); } else { break; } } return 0; }
這是執行它的輸出:
$ ./a.out File descriptor opened: 1 File descriptor opened: 1 [snip] File descriptor opened: 1 File descriptor opened: 1
編輯基於其中一個答案,我
strace
在執行檔上執行,發現open
確實返回了多個文件描述符,但由於某種原因,所有這些文件描述符都沒有列印出來。為什麼會這樣?
- 有點不相關,但在 fds 0-2 中使用 stdio 流的慣例不就是這樣 - 慣例嗎?例如,如果初始化序列將輸入/輸出文件描述符分配給其他東西 - 它會以某種方式影響其子代如何進行 I/O 操作嗎?
這實際上是3個問題。立即處理#2,因為程序不正確:
while ((fd = open("sample.txt", O_RDWR) > 0)) {
你可能是說
while ((fd = open("sample.txt", O_RDWR)) > 0) {
使用不正確放置的括號,您只測試是否
fd
大於零(因為文件描述符 0、1 和 2 是打開的,這可能是一個很好的假設)。對於#1:
open
呼叫(成功時)被定義為返回不同的文件描述符。如果設備無法重新打開,open
將返回-1
.對於#3:當然,這是一個約定,但也在POSIX標準中。其他系統使用了其他約定,包括為每個程序設置第四個開放流。
進一步閱讀:使用您的 Aegis 環境(1988 年 7 月)
參見第 6-9 頁,其中說 Apollo Domain/OS 有錯誤輸入和**輸出*