Here's an alternative to curl_multi_select() which addresses your desire for being able to add arbitrary file descriptors. Workflow here is:
long read_fds, write_fds;
curl_multi_getinfo(multi, CURLMINFO_NUM_READ_FDS, &read_fds);
curl_multi_getinfo(multi, CURLMINFO_NUM_WRITE_FDS, &write_fds);
int *rfds = calloc(read_fds, sizeof(int));
int *wfds = calloc(write_fds, sizeof(int));
curl_multi_fdvec(multi, rfds, wfds, NULL);
Then the caller can put into fd_set or struct pollfd as desired, allocating extra space for external fds if desired.
LMK what you think of this approach, and I can add manpages/tests if you like it better.
Note that although I included support for exception fds, there's no internal plumbing for it in keeping with curl_multi_fdset().
Add curl_multi_getinfo() method
Add curl_multi_fdvec() method
Merge branch 'fdvec' of https://github.com/sgolemon/curl into fdvec
Ick, dunno what I did to my repo to make it look like this. Will resubmit a clean pull if the overall strat looks okay. :/
I think the primary reason I went this direction instead of what you propose (which is certainly simpler to use) was to allow more flexibility in how poll() gets called. For my purposes, I don't actually need the flexibility so I wouldn't mind the approach you describe at all.
Want me to do the work and submit a pull request for that?