CURLOPT_OPENSOCKETDATA(3)

πŸ’… CURLOPT_OPENSOCKETDATA(3) β€” like, the libcurl manual but make it make sense

okay bestie, so before we even start β€” this page lives in the Library Functions Manual for libcurl, and it's literally all about one tiny little thing: a pointer that you hand to libcurl and it goes "mm, yes, noted" and then passes it straight along to your callback. no cap. 🫢


✨ NAME ✨

CURLOPT_OPENSOCKETDATA β€” the pointer that gets passed to your open socket callback πŸ’«


🌸 SYNOPSIS 🌸

#include <curl/curl.h>

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_OPENSOCKETDATA, void *pointer);

πŸ¦‹ DESCRIPTION πŸ¦‹

So here's the vibe 😌 β€” you pass in a pointer, and libcurl is so well-behaved about it. It does not touch it, does not poke at it, does not peek inside. It just holds onto it and then passes it as the first argument to the open socket callback that you set with CURLOPT_OPENSOCKETFUNCTION(3). That's it. That's the whole thing. It's giving "trusted messenger" energy. 🧚


πŸŽ€ DEFAULT πŸŽ€

NULL

(yeah. nothing. empty. the void. πŸ™ˆ)


🌈 PROTOCOLS 🌈

This functionality affects all supported protocols β€” every single one of them, periodt. πŸ‘‘


⭐ EXAMPLE ⭐

okay so this example is genuinely iconic β€” the whole point is making libcurl use a socket, sockfd, that you already established yourself πŸ”₯

/* make libcurl use the already established socket 'sockfd' */

static curl_socket_t opensocket(void *clientp,
                                curlsocktype purpose,
                                struct curl_sockaddr *address)
{
  curl_socket_t sockfd;
  sockfd = *(curl_socket_t *)clientp;
  /* the actual externally set socket is passed in via the OPENSOCKETDATA
     option */
  return sockfd;
}

static int sockopt_callback(void *clientp, curl_socket_t curlfd,
                            curlsocktype purpose)
{
  return CURL_SOCKOPT_ALREADY_CONNECTED;
}

int main(void)
{
  CURL *curl = curl_easy_init();
  if(curl) {
    CURLcode result;
    extern int sockfd; /* the already connected one */

    /* libcurl thinks that you connect to the host
     * and port that you specify in the URL option. */
    curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
    /* call this function to get a socket */
    curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
    curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);

    /* call this function to set options for the socket */
    curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);

    result = curl_easy_perform(curl);

    curl_easy_cleanup(curl);
  }
}

like β€” notice how &sockfd gets handed over as the data, and then opensocket casts clientp back to curl_socket_t * and dereferences it. the full circle moment. we love to see it. πŸ’–


πŸ’œ AVAILABILITY πŸ’œ

Added in curl 7.17.1 β€” so it's been slaying since the old days, fr fr. ⏳✨


πŸ”₯ RETURN VALUE πŸ”₯

curl_easy_setopt(3) returns a CURLcode indicating success or error.

CURLE_OK (that's 0) means everything was OK πŸŽ‰ β€” and non-zero means an error occurred, so go check out libcurl-errors(3) to find out what went wrong. 😭


πŸ’€ SEE ALSO πŸ’€

(go read them. they're the friend group. iykyk. πŸ’…)


k bye bestie, this page came from libcurl, dated 2026-10-12 πŸ—“οΈπŸŒΈ β€” go forth and open those sockets πŸ‘‘βœ¨

πŸ“¦ where this page comes from