Je tente depuis un certain temps d'interroger un ensemble de tubes nommés et je reçois toujours une réponse immédiate de POLLNVAL sur n'importe quel descripteur de fichier de canal nommé. Après avoir trouvé ce blog post about broken polling in OS X je suis assez certain qu'il s'agit d'un bug d'OS X.On dirait que OS X a un bug lors de l'utilisation de poll() sur un tube nommé (FIFO) ... un expert peut-il confirmer?
Je prévois déjà de passer mon code à l'aide de sockets UDP, mais je voulais demander SO pour vérification à ce sujet a) que je suis sûr que c'est vraiment cassé, et b) à des fins de documentation.
Voici une version dépouillée du code que j'ai écrit (bien que le code dans le lien ci-dessus, je l'ai testé, il explique assez bien):
#includes
...
....
#
static const char* first_fifo_path = "/tmp/fifo1";
static const char* second_fifo_path = "/tmp/fifo2";
int setup_read_fifo(const char* path){
int fifo_fd = -1;
if(mkfifo(path, S_IRWXU | S_IRWXG | S_IRWXO))
perror("error calling mkfifo()... already exists?\n");
if((fifo_fd = open(path, O_RDONLY | O_NDELAY)) < 0)
perror("error calling open()");
return fifo_fd;
}
void do_poll(int fd1, int fd2){
char inbuf[1024];
int num_fds = 2;
struct pollfd fds[num_fds];
int timeout_msecs = 500;
fds[0].fd = fd1;
fds[1].fd = fd2;
fds[0].events = POLLIN;
fds[1].events = POLLIN;
int ret;
while((ret = poll(fds, num_fds, timeout_msecs)) >= 0){
if(ret < 0){
printf("Error occured when polling\n");
printf("ret %d, errno %d\n", ret, errno);
printf("revents = %xh : %xh \n\n", fds[0].revents, fds[1].revents);
}
if(ret == 0){
printf("Timeout Occurred\n");
continue;
}
for(int i = 0; i< num_fds; i++){
if(int event = fds[i].revents){
if(event & POLLHUP)
printf("Pollhup\n");
if(event & POLLERR)
printf("POLLERR\n");
if(event & POLLNVAL)
printf("POLLNVAL\n");
if(event & POLLIN){
read(fds[i].fd, inbuf, sizeof(inbuf));
printf("Received: %s", inbuf);
}
}
}
}
}
int main (int argc, char * const argv[]) {
do_poll(setup_read_fifo(first_fifo_path), setup_read_fifo(second_fifo_path));
return 0;
}
cette sortie:
$ ./executive POLLNVAL POLLNVAL POLLNVAL POLLNVAL POLLNVAL POLLNVAL POLLNVAL POLLNVAL POLLNVAL ...
ad nauseam.
Quelqu'un d'autre est-il confronté à cela? C'est un vrai bug, n'est-ce pas?
Les délais d'attente sont un comportement correct sans écriture. J'ai écrit un programme d'écriture simple pour d'autres tests et le programme dans le Q lit l'amende FIFO sur Linx/OpenBSD et échoue misérablement sur OS X (même problème POLLNVAL). – dwc