Commit 77e17267 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

curl_multi_wait: never return -1 in 'numfds'

Such a return value isn't documented but could still happen, and the
curl tool code checks for it. It would happen when the underlying
Curl_poll() function returns an error. Starting now we mask that error
as a user of curl_multi_wait() would have no way to handle it anyway.

Reported-by: Jay Satiro
Closes #707
parent b6665c7a
Loading
Loading
Loading
Loading
+11 −10
Original line number Original line Diff line number Diff line
@@ -811,6 +811,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
  unsigned int curlfds;
  unsigned int curlfds;
  struct pollfd *ufds = NULL;
  struct pollfd *ufds = NULL;
  long timeout_internal;
  long timeout_internal;
  int retcode = 0;


  if(!GOOD_MULTI_HANDLE(multi))
  if(!GOOD_MULTI_HANDLE(multi))
    return CURLM_BAD_HANDLE;
    return CURLM_BAD_HANDLE;
@@ -903,18 +904,20 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
  }
  }


  if(nfds) {
  if(nfds) {
    int pollrc;
    /* wait... */
    /* wait... */
    infof(data, "Curl_poll(%d ds, %d ms)\n", nfds, timeout_ms);
    pollrc = Curl_poll(ufds, nfds, timeout_ms);
    i = Curl_poll(ufds, nfds, timeout_ms);
    DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
                 nfds, timeout_ms, pollrc));


    if(i) {
    if(pollrc > 0) {
      unsigned int j;
      retcode = pollrc;
      /* copy revents results from the poll to the curl_multi_wait poll
      /* copy revents results from the poll to the curl_multi_wait poll
         struct, the bit values of the actual underlying poll() implementation
         struct, the bit values of the actual underlying poll() implementation
         may not be the same as the ones in the public libcurl API! */
         may not be the same as the ones in the public libcurl API! */
      for(j = 0; j < extra_nfds; j++) {
      for(i = 0; i < extra_nfds; i++) {
        unsigned short mask = 0;
        unsigned short mask = 0;
        unsigned r = ufds[curlfds + j].revents;
        unsigned r = ufds[curlfds + i].revents;


        if(r & POLLIN)
        if(r & POLLIN)
          mask |= CURL_WAIT_POLLIN;
          mask |= CURL_WAIT_POLLIN;
@@ -923,16 +926,14 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
        if(r & POLLPRI)
        if(r & POLLPRI)
          mask |= CURL_WAIT_POLLPRI;
          mask |= CURL_WAIT_POLLPRI;


        extra_fds[j].revents = mask;
        extra_fds[i].revents = mask;
      }
      }
    }
    }
  }
  }
  else
    i = 0;


  free(ufds);
  free(ufds);
  if(ret)
  if(ret)
    *ret = i;
    *ret = retcode;
  return CURLM_OK;
  return CURLM_OK;
}
}