Por lo que he estado leyendo en el sitio web de Open Group en fcntl
, open
, read
y write
, me da la impresión de que si O_NONBLOCK
se encuentra en un descriptor de archivo, y por lo tanto si no-bloqueo de E/S se utiliza con el descriptor, debe ser una propiedad de ese descriptor de archivo en lugar del archivo subyacente. Ser propiedad del descriptor de archivo significa, por ejemplo, que si duplico un descriptor de archivo o abro otro descriptor en el mismo archivo, entonces puedo usar E/S de bloqueo con una y E/S sin bloqueo con la otra.¿Se está estableciendo O_NONBLOCK como una propiedad del descriptor de archivo o del archivo subyacente?
Experimentando con un FIFO, sin embargo, parece que no es posible tener un descriptor de E/S de bloqueo y un descriptor de E/S sin bloqueo en el FIFO simultáneamente (entonces O_NONBLOCK
es una propiedad del subyacente presentar [FIFO]):
#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;
}
Esto me deja pensando: ¿alguna vez es posible tener un no-bloqueo descriptor de e/S y el bloqueo de descriptor de e/S en el mismo archivo y si es así, de qué depende en el tipo de archivo (archivo normal, FIFO, archivo especial de bloque, archivo especial de caracteres, socket, etc.)?
Me pregunto acerca de esto porque si O_NONBLOCK se establece es una propiedad del archivo subyacente, entonces una llamada para abrir un archivo con O_NONBLOCK * no * establecido en oflags * podría * devolver un descriptor de archivo con el indicador O_NONBLOCK. –