Domanda

Da quello che ho letto su Il sito Open Il gruppo su fcntl , open , read , e write , ho l'impressione che se O_NONBLOCK si trova su un descrittore di file, e quindi se la non-blocking I / O viene utilizzato con il descrittore, deve essere una proprietà di quel file descrittore piuttosto che il file sottostante. Essendo una proprietà dei mezzi descrittori di file, ad esempio, che se duplicare un descrittore di file o aprire un altro descrittore per lo stesso file, quindi posso usare il blocco di I / O con uno e non-blocking I / O con l'altra.

Esperimenti con una FIFO, tuttavia, sembra che non è possibile avere un O descrittore / descrittore O bloccante I e non-blocking I / al FIFO contemporaneamente (quindi se O_NONBLOCK è set è una proprietà del file sottostante [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;
}

Questo mi lascia pensare: è mai possibile avere un descrittore non-blocking I / O e il blocco di I / O descrittore per lo stesso file e se è così, non si dipende dal tipo di file (file normale, FIFO, bloccare file speciale, file speciale carattere, presa, ecc.)?

È stato utile?

Soluzione

O_NONBLOCK è una proprietà della descrizione del file aperto, non del descrittore di file, né il file sottostante.

Sì, si potrebbe avere descrittori di file separati aprono per lo stesso file, uno dei quali sta bloccando e l'altro dei quali è non-blocking.

È necessario distinguere tra un FIFO (creato utilizzando mkfifo() ) ed un condotto (creata usando pipe() ).

Si noti che lo stato di blocco è una proprietà della 'descrizione aprire il file', ma nei casi più semplici, c'è una corrispondenza uno-a-uno tra i descrittori di file e descrizioni dei file aperti. Il href="http://www.opengroup.org/onlinepubs/9699919799/functions/open.html" rel="noreferrer"> open() chiamata di funzione

Quando si utilizza dup() uno , avete due descrittori di file sharing descrizione file aperto, e le proprietà appartengono alla descrizione file aperto. La descrizione di fcntl() dice che F_SETFL colpisce la descrizione del file aperto associato con la descrittore di file. Si noti che lseek() regola la posizione del file di descrizione del file aperto associato con la descrittore di file -. in modo che colpisce gli altri descrittori di file duplicati da quello originale

Rimozione della gestione dal codice di ridurlo errore, si ha:

int fds[2];
pipe(fds);
int fd0_dup = dup(fds[0]);
fcntl(fd0_dup, F_SETFL, fcntl(fd0_dup, F_GETFL) | O_NONBLOCK);

Ora sia fd0_dup e FDS [0] si riferiscono alla stessa descrizione di file aperto (a causa del dup()), quindi l'operazione fcntl() ha interessato sia i descrittori di file.

if ((fcntl(fds[0], F_GETFL) & O_NONBLOCK)) { ... }

Quindi il comportamento osservato qui è richiesto da POSIX.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top