curl_multi_fdset(3)

πŸ’… curl_multi_fdset(3) β€” straight from the libcurl Library Functions Manual, bestie

✨ NAME ✨

  • curl_multi_fdset β€” extract file descriptor information from a multi handle 🫢

πŸŽ€ SYNOPSIS πŸŽ€

#include <curl/curl.h>

CURLMcode curl_multi_fdset(CURLM *multi_handle,
                           fd_set *read_fd_set,
                           fd_set *write_fd_set,
                           fd_set *exc_fd_set,
                           int *max_fd);

πŸ’– DESCRIPTION πŸ’–

Okay so this function is literally how you extract file descriptor information from a given multi_handle. libcurl hands you back its own fd_set sets. Your app can use those to select() on β€” iconic β€” but bestie, please be sure to FD_ZERO them before calling this function, because curl_multi_fdset(3) only adds its own descriptors. It does not zero or otherwise remove any others. And curl_multi_perform(3) should be called as soon as one of them is ready to be read from or written to. Periodt. πŸ’…

The read_fd_set argument should point to an object of type fd_set that on return specifies the file descriptors to be checked for being ready to read. πŸ‘‘

The write_fd_set argument should point to an object of type fd_set that on return specifies the file descriptors to be checked for being ready to write. ✨

The exc_fd_set argument should point to an object of type fd_set that on return specifies the file descriptors to be checked for error conditions. 🚨

If no file descriptors are set by libcurl, max_fd contains -1 when this function returns. Otherwise it contains the highest descriptor number libcurl set. When libcurl returns -1 in max_fd, it is because libcurl currently does something that is not possible for your application to monitor with a socket β€” and unfortunately you can then not know exactly when the current action is completed using select(). 😭 You then need to wait a while before you proceed and call curl_multi_perform(3) anyway. How long to wait? Unless curl_multi_timeout(3) gives you a lower number, we suggest 100 milliseconds or so, but you may want to test it out in your own particular conditions to find a suitable value. 🧚

When doing select(), you should use curl_multi_timeout(3) to figure out how long to wait for action. Call curl_multi_perform(3) even if no activity has been seen on the fd_sets after the timeout expires, as otherwise internal retries and timeouts may not work as you would think and want. πŸ”₯

⚠️ If one of the sockets used by libcurl happens to be larger than what can be set in an fd_set β€” which on POSIX systems means that the file descriptor is larger than FD_SETSIZE β€” then libcurl tries to not set it. Setting a too large file descriptor in an fd_set implies an out of bounds write which can cause crashes, or worse. πŸ’€ The effect of NOT storing it might possibly save you from the crash, but makes your program NOT wait for sockets it should wait for...

🌈 PROTOCOLS 🌈

This functionality affects all supported protocols ✨

πŸ¦‹ EXAMPLE πŸ¦‹

int main(void)
{
  fd_set fdread;
  fd_set fdwrite;
  fd_set fdexcep;
  int maxfd;
  int rc;
  CURLMcode mresult;
  struct timeval timeout = { 1, 0 };

  CURLM *multi = curl_multi_init();

  do {

    /* call curl_multi_perform() */

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* get file descriptors from the transfers */
    mresult = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mresult != CURLM_OK) {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mresult);
      break;
    }

    /* wait for activity on one of the sockets */
    rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

  } while(!mresult);
}

🌸 AVAILABILITY 🌸

Added in curl 7.9.6 πŸ’–

⭐ RETURN VALUE ⭐

This function returns a CURLMcode indicating success or error.

CURLM_OK (0) means everything was OK, non-zero means an error occurred, see libcurl-errors(3). 🫢

πŸ‘‘ SEE ALSO πŸ‘‘


With love from your libcurl bestie πŸ’– β€” source/version: libcurl, date: 2026-10-12 πŸŽ€

πŸ“¦ where this page comes from