Seeing two accept events on epoll
<p>I'm playing around with epoll on Linux for the first time and see some strange behavior. Specificall, when I connect with a client to a socket, I see two events emitted by epoll_wait on the server side. When I call accept on the second attempt I get a "temporary unavailable" error.</p>

<p>Here's the simple client code:</p>

<pre><code>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/un.h&gt;
#include &lt;unistd.h&gt;

const char* msg = "friendly ping";

int main(int argc, char** argv) {
  if (argc != 2) {
    fprintf(stderr, "Usage: %s &lt;socket&gt;\n", argv[0]);
    exit(-1);
  }

  int sock = socket(AF_UNIX, SOCK_STREAM, 0);
  if (sock &lt; 0) {
    perror("socket");
    exit(-1);
  }

  struct sockaddr_un addr;
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path) - 1);

  if (connect(sock, (struct sockaddr*)&amp;addr, sizeof(addr)) == -1) {
    perror("Error connecting");
    exit(-1);
  }

  write(sock, msg, strlen(msg));
  close(sock);

  return 0;
}
</code></pre>

<p>The server code is the following:</p>

<pre><code>#include &lt;errno.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/epoll.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/un.h&gt;
#include &lt;unistd.h&gt;

const int kMaxEvents = 100;
const char *kSocketFile = "dummy_socket";

void MakeNonBlocking(int fd) {
  int flags, s;

  flags = fcntl (fd, F_GETFL, 0);
  if (flags == -1) {
    perror ("fcntl");
    exit(-1);
  }

  flags |= O_NONBLOCK;
  s = fcntl (fd, F_SETFL, flags);
  if (s == -1) {
    perror ("fcntl");
    exit(-1);
  }
}

void AcceptConnections(int sock, int epoll_fd) {
  struct epoll_event event;
  event.data.fd = sock;
  event.events = EPOLLIN;

  int insock = accept(sock, NULL, NULL);
  if (insock &lt; 0) {
    perror("Error accepting connection");
    exit(-1);
  }

  MakeNonBlocking(insock);

  int s = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, insock, &amp;event);
  if (s &lt; 0) {
    perror("Epoll error adding accepted connection");
    exit(-1);
  }
  printf("Connection processed.\n");
}

int main(void) {
  int sock, efd, n;
  struct sockaddr_un addr;
  struct epoll_event event;
  struct epoll_event *events;
  char buf[1024];

  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) &lt; 0) {
    perror("Error creating socket.");
    exit(-1);
  }

  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, kSocketFile, sizeof(addr.sun_path) - 1);
  if (bind(sock, (struct sockaddr *)&amp;addr, sizeof(addr)) == -1) {
    perror("Error binding name to socket");
    exit(-1);
  }

  if (listen(sock, SOMAXCONN) &lt; 0) {
    perror("Error listening on socket");
    exit(-1);
  }

  MakeNonBlocking(sock);

  if ((efd = epoll_create1(0)) &lt; 0) {
    perror("Epoll initialization error");
    exit(-1);
  }

  event.data.fd = sock;
  event.events = EPOLLIN;
  if (epoll_ctl(efd, EPOLL_CTL_ADD, sock, &amp;event) &lt; 0) {
    perror("Epoll error adding socket");
    exit(-1);
  }

  events = (struct epoll_event*) calloc(kMaxEvents, sizeof(event));
  if (!events) {
    perror("Error allocating event buffers");
    exit(-1);
  }

  while(1) {
    printf("Calling epoll_wait\n");
    if ((n = epoll_wait(efd, events, kMaxEvents, -1)) == -1) {
      perror("epoll_wait failure");
      exit(-1);
    }

    for (int i = 0; i &lt; n; ++i) {
      printf("Checking event for fd = %d\n", events[i].data.fd);
      if (sock == events[i].data.fd) {
        AcceptConnections(sock, efd);
        continue;
      }

      int count = read(events[i].data.fd, buf, 100);
      if (count == 0) {
        close(events[i].data.fd);
      }
      write(1, buf, count);
    }
  }

  free(events);
  close(efd);
  close(sock);
  unlink(kSocketFile);
  return 0;
}
</code></pre>

<p>When I run the server and connect to the client I get:</p>

<pre><code>Calling epoll_wait
Checking event for fd = 3
Connection processed.
Calling epoll_wait
Checking event for fd = 3
Error accepting connection: Resource temporarily unavailable
</code></pre>

<p>In other words, I see two events on the listening socket. Any ideas?</p>