lundi 15 novembre 2021

poll() always set POLLIN on AF_UNIX socket after peer close its socket

Why POLLIN(1) is set by last poll()?

$ g++ temp.cpp -std=gnu++11 && ./a.out
poll: 0
poll: 17
read: 4
read: 0
poll: 17
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <poll.h>
#include <map>
#include <string>
#include <list>
#include <iostream>


int main(void)
{
  int sock = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
  if (-1 == sock) {
    assert(!"sock");
    throw std::runtime_error(strerror(errno));
  }
  
  int sock1 = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
  if (-1 == sock) {
    assert(!"sock1");
    throw std::runtime_error(strerror(errno));
  }

  struct sockaddr_un addr;
  memset(&addr, 0, sizeof(addr));
  addr.sun_family = AF_UNIX;
  strcpy(addr.sun_path, "/tmp/temp.sock");
  unlink(addr.sun_path);
  if (-1 == bind(sock, (struct sockaddr*)&addr, sizeof(addr))) {
    assert(!"bind");
  }

  if (-1 == listen(sock, 1)) {
    assert(!"listen");
  }

  if (connect(sock1, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
    assert(!"connect");
  }

  int sock2 = accept(sock, NULL, NULL);
  if (-1 == sock2) {
    assert(!"accept");
  }

  struct pollfd poll_fds;
  poll_fds.fd = sock1;
  poll_fds.events = POLLIN;
  poll_fds.revents = 0;
  poll(&poll_fds, 1, 0);
  std::cout << "poll: " << poll_fds.revents << std::endl;
  
  char buffer[4];
  write(sock2, buffer, 4);
  close(sock2);
  poll_fds.revents = 0;
  poll(&poll_fds, 1, 0);
  std::cout << "poll: " << poll_fds.revents << std::endl;
  std::cout << "read: " << read(sock1, buffer, 5) << std::endl;
  std::cout << "read: " << read(sock1, buffer, 5) << std::endl;
  poll_fds.revents = 0;
  poll(&poll_fds, 1, 0);
  std::cout << "poll: " << poll_fds.revents << std::endl;
  return 0;
}
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

There is no more data for read, but poll() is set POLLIN.

No need to read later. It looks like your post is mostly code; please add some more details. It looks like your post is mostly code; please add some more details. It looks like your post is mostly code; please add some more details. It looks like your post is mostly code; please add some more details.

Aucun commentaire:

Enregistrer un commentaire