title: Confusion over poll() and recvfrom()
body: <p>I'm trying to implement a protocol in C that sends/receives raw Ethernet frames, and I've ran into some problems using <code>poll()</code> and <code>recvfrom()</code> in a Linux environment. I think my problem is mostly conceptual, so I'll avoid posting my code for now.</p>
  
  <p>I have two sockets for incoming data, and <code>poll()</code> is being used to indicate when data is ready on either socket through its return value and the state of the associated <code>pollfd</code> structure. This is working for me right now when I first run the program. For the sake of testing I'm only interested in ARP frames, and I'm able to use <code>poll()</code> to wait for an ARP frame to arrive. When it arrives, I call <code>recvfrom()</code> to copy the data into a location where I can process it. All of this is working fine. </p>
  
  <p>The problem is that subsequent calls to <code>poll()</code> continue to report that data is ready to be read from the socket even when no new data has arrived in the socket. Once I've called <code>recvfrom()</code> and read the data from the socket, I'd like <code>poll()</code> to wait until a new frames arrive before reporting that data is ready. I've never used <code>poll()</code> before, so I'm not sure if there is an explicit step needed to "clear" the descriptor so that it will stop causing <code>poll()</code> to report data being ready until a new frame comes in. I'm clearing the <code>revents</code> member of the <code>pollfd</code> structures before calling <code>poll()</code>, but each call to <code>poll()</code> is setting the value of <code>revents</code> back to 1.</p>
  
  <p>I've looked through the <code>poll()</code> man pages and I haven't had any luck finding information on this. I feel like I'm misunderstanding how sockets/polling works at a high level, so any help would be appreciated.</p>
  
  <p><strong>[edit]</strong> 
  Here's the majority of my code. I've actually simplified the code for this example by including only a single socket. All of this is also encapsulated in classes and spread out, but re-writing it like this reproduces my problems. My final code has error-checking on the API calls and copies my receive buffer to process the frame rather than just printing the contents, but other than that it's pretty much the same. </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;poll.h&gt;
  #include &lt;linux/if_ether.h&gt;
  
  int main()
  {
  
      uint8_t sendBuffer_[1536];
      uint8_t receiveBuffer_[1536];
      struct pollfd pollStruct[1];
  
      printf("Making socket...");
      int mySocket = socket( AF_PACKET, SOCK_RAW, htons(ETH_P_ARP) );
      fcntl(mySocket, F_SETFL, O_NONBLOCK);
      char *options;
      options = "eth0";
      setsockopt(mySocket, SOL_SOCKET, SO_BINDTODEVICE, options, 4);
      printf("Descriptor: %i\n", mySocket);
  
      while(1)
      {
          pollStruct[0].fd = mySocket;
          pollStruct[0].events = POLLIN;
          pollStruct[0].revents = 0;
  
          if( poll(pollStruct, 1, 0) == 1)
          {
              printf("New Frame Arrived: ");
              uint16_t frameLength = recvfrom( mySocket, receiveBuffer_, 1536, 0, NULL, NULL);
  
              printf("Destination MAC: ");
              for ( uint8_t i = 0; i &lt; 6; ++i ) {
                  printf("0x%x ", receiveBuffer_[i]);
              }
  
              printf("\nSource MAC: ");
              for ( uint8_t i = 0; i &lt; 6; ++i ) {
                  printf("0x%x ", receiveBuffer_[i + 6]);
              }
  
              printf("\nEtherType: ");
              for ( uint8_t i = 0; i &lt; 2; ++i ) {
                  printf("0x%x ", receiveBuffer_[i + 12]);
              }
  
              printf("\nPayload: ");
              for ( uint32_t i = 14; i &lt; frameLength; ++i ) {
                  printf("0x%x ", receiveBuffer_[i]);
              }
              printf("\n");
  
              //Clear buffer
              for ( uint32_t i = 0; i &lt; frameLength; ++i )
                          receiveBuffer_[i] = 0;
          }
      }
  }
  </code></pre>
  
  <p>I didn't mention this originally, but I'm trying to deploy this code on a Beaglebone Black. When I run this program in a VM with Ubuntu compiled using GCC, it works as I'd expect. After receiving/printing a frame, the program visually idles until a new one arrives. When I cross-compile the program and run it, the program continuously prints the same packet until a new one arrives. Since I'm clearing <code>receiverBuffer[]</code> whenever <code>recvfrom()</code> returns, <code>recvfrom()</code> doesn't seem to be clearing the data from its internal buffer once it's copied into my buffer, since it is continuously copying the data. </p>