Non-blocage de lire sur un tuyau
Peut-on faire de la non-blocage I/O sur un tuyau? fcntl ne parvient pas à définir O_NONBLOCK. Page 918 Linux, l'Interface de Programmation comprend un tableau, " la Sémantique de la lecture de n octets à partir de tube ou FIFO (p)'. Ce tableau présente le comportement des tubes et les FIFO avec une colonne intitulée O_NONBLOCK est-il activé? Cela signifie que vous pouvez définir l'attribut O_NONBLOCK sur un tuyau. Est-ce correct? Le code suivant ne parvient pas à définir le drapeau, fcntl(2) ne signale pas une erreur, même si.
#include <fcntl.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define SLEEP 1
int
main(int argc, char *argv[]) {
pid_t childPid;
int pfd[2];
int nread, flags;
int c = 'a';
setbuf(stdout, NULL);
if (pipe(pfd) == -1) {
printf("error: pipe");
exit(EXIT_FAILURE);
}
switch (childPid = fork()) {
case -1:
printf("error: fork");
exit(EXIT_FAILURE);
case 0: /* child */
if (close(pfd[0]) == -1) {
printf("child: close pfd read");
exit(EXIT_FAILURE);
}
sleep(SLEEP);
_exit(EXIT_SUCCESS);
default:
break;
/* parent falls through */
}
if (close(pfd[1]) == -1) {
printf("parent: close pipe write");
exit(EXIT_FAILURE);
}
flags = fcntl(pfd[0], F_GETFD);
flags |= O_NONBLOCK;
if (fcntl(pfd[0], F_SETFD, flags))
perror("fcntl");
/* verify flags set correctly */
flags = fcntl(pfd[0], F_GETFD);
if (!(flags & O_NONBLOCK)) {
printf("failed to set O_NONBLOCK\n");
exit(EXIT_FAILURE);
}
wait(NULL);
exit(EXIT_SUCCESS);
}
Il ressemble à un bug dans le
F_GETFD
opération. J'ai confirmé que cela n'en fait définir le descripteur de non-blocage et de l'exploitation n'est pas en bloc, mais F_GETFD
renvoie toujours zéro.OriginalL'auteur Tobin | 2016-04-17
Vous devez vous connecter pour publier un commentaire.
Il n'y a rien de spécial à pipe et O_NONBLOCK. L'exemple suivant fonctionne comme prévu. Je n'ai pas vérifié tous les retval de tous les appeler pour faire un exemple un peu plus lisible. Une application du monde réel doit effectuer les vérifications.
Après avoir écrit mon exemple, j'ai inspecter votre code et trouvé:
S'il vous plaît changer
F_SETFD
àF_SETFL
et également à l'opération. Vous ne voudriez pas changer lefile descriptor flags
mais lafile descriptor status flags
🙂De
man 3 fcntl
:OriginalL'auteur Klaus