在命名管(FIFO)上使用poll()时,OS X确实有一个错误……专家可以证实吗?

StackOverflow https://stackoverflow.com/questions/591826

  •  09-09-2019
  •  | 
  •  

我一直在尝试从一组命名的Pipes进行调查,现在我一直在任何命名的管子文件描述符上都立即得到Pollnval的响应。找到这个 关于OS X中的民意调查的博客文章 我很确定这是OS X中的错误。

我已经计划将代码切换到使用UDP插座,但是我想请问这一点a),以便我确定它确实被打破了,b)出于文档目的。

这是我编写的代码的删除版本(尽管我测试过的链接中的代码很好地将其拼写出来):

#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;
}

这输出:

$ ./executive 
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
...

ad恶心。

有人遇到这个吗?这是一个真正的错误吧?

有帮助吗?

解决方案

这似乎是一个真正的错误。它按照Linux和OpenBSD的预期工作,并且如您在OS X上所描述的那样失败。

其他提示

OSX 10.4.1,我可以确认行为。相同的代码在Linux上可以正常工作(只要超时消息很好)即可。所有证据,包括这 - http://www.virtualbox.de/changeset/12347 - 暗示存在一个真正的问题。

Yup, known bug. I think the poll breakage is only since 10.4, we had to deal with it in Fink. Glib's configure.in has a test for this, so you can be sure that you're not imagining it. (Well, not precisely this, glib tests for poll on devices, not fifos.)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top