從我一直在閱讀上由The Open Group網站上fcntl
,open
,read
和write
,我得到的印象是,是否O_NONBLOCK
被設置在一個文件描述符,因此無論是非阻塞I/O是用來與描述符應該是該文件描述符的屬性,而不是底層文件。作爲文件描述符裝置的屬性,例如,如果我複製一個文件描述符或打開另一個描述符到相同的文件,然後我可以使用阻塞I/O與一個並且與其它非阻塞I/O。是否將O_NONBLOCK設置爲文件描述符或基礎文件的屬性?
與FIFO進行實驗,但是,看來,它不可能同時具有阻塞I/O描述符和非阻塞I/O描述符的FIFO(因此無論O_NONBLOCK
設置是底層的一個屬性文件[先進先出]):
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fds[2];
if (pipe(fds) == -1) {
fprintf(stderr, "`pipe` failed.\n");
return EXIT_FAILURE;
}
int fd0_dup = dup(fds[0]);
if (fd0_dup <= STDERR_FILENO) {
fprintf(stderr, "Failed to duplicate the read end\n");
return EXIT_FAILURE;
}
if (fds[0] == fd0_dup) {
fprintf(stderr, "`fds[0]` should not equal `fd0_dup`.\n");
return EXIT_FAILURE;
}
if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) {
fprintf(stderr, "`fds[0]` should not have `O_NONBLOCK` set.\n");
return EXIT_FAILURE;
}
if (fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK) == -1) {
fprintf(stderr, "Failed to set `O_NONBLOCK` on `fd0_dup`\n");
return EXIT_FAILURE;
}
if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) {
fprintf(stderr, "`fds[0]` should still have `O_NONBLOCK` unset.\n");
return EXIT_FAILURE; // RETURNS HERE
}
char buf[1];
if (read(fd0_dup, buf, 1) != -1) {
fprintf(stderr, "Expected `read` on `fd0_dup` to fail immediately\n");
return EXIT_FAILURE;
}
else if (errno != EAGAIN) {
fprintf(stderr, "Expected `errno` to be `EAGAIN`\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
這讓我思考:有沒有可能有一個非阻塞I/O描述符和阻塞I/O描述符相同的文件,如果是這樣,那麼它取決於關於文件的類型(常規文件,FIFO,塊特殊文件,字符特殊文件,套接字等)?
我很想知道這件事,因爲如果O_NONBLOCK被設置爲底層文件的屬性,那麼打開帶有O_NONBLOCK *的文件的一個調用*不在* oflags *中設置*然而可能會返回帶有O_NONBLOCK標誌的文件描述符。 – 2010-05-22 22:06:52