CURLOPT_CHUNK_DATA(3)

πŸ’… CURLOPT_CHUNK_DATA β€” bestie, it's literally just a pointer you hand to your chunk callbacks

okay so real talk: CURLOPT_CHUNK_DATA(3) is the curl_easy_setopt option that lets you smuggle your own pointer into the FTP chunk callbacks. That's it. That's the whole vibe. This page lives in the Library Functions Manual, and it's short and sweet and honestly kind of iconic for it. πŸŽ€


✨ SYNOPSIS ✨

#include <curl/curl.h>

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

like, one function call. one pointer. we love a low-effort queen. πŸ‘‘


🌸 DESCRIPTION 🌸

You pass in a pointer, and here's the slay part: libcurl does not touch it. Not even a little. It's untouched, unbothered, moisturised, in its lane. πŸ§–β€β™€οΈ

That pointer then gets handed straight to your callbacks as the ptr argument β€” specifically to the ones you set with CURLOPT_CHUNK_BGN_FUNCTION(3) and CURLOPT_CHUNK_END_FUNCTION(3).

so like… it's your little bag of stuff πŸ‘œ β€” your FILE *, your state struct, whatever β€” riding along into callback land. no cap, that's the entire functionality.


πŸ¦‹ DEFAULT πŸ¦‹

NULL

(as in, nothing. nada. the void. πŸ’€ if you don't set it, your ptr is just NULL, so don't be surprised.)


🌈 PROTOCOLS 🌈

This functionality affects ftp only. ftp girlies only, everyone else go home. 🐟


πŸ’– EXAMPLE πŸ’–

okay so here's the full glow-up example, copied exactly, no cap:

#include <stdio.h>

struct callback_data {
   FILE *output;
};

static long file_is_coming(struct curl_fileinfo *finfo,
                           void *ptr,
                           int remains)
{
  struct callback_data *data = ptr;
  printf("%3d %40s %10luB ", remains, finfo->filename,
         (unsigned long)finfo->size);

  switch(finfo->filetype) {
  case CURLFILETYPE_DIRECTORY:
    printf(" DIR\n");
    break;
  case CURLFILETYPE_FILE:
    printf("FILE ");
    break;
  default:
    printf("OTHER\n");
    break;
  }

  if(finfo->filetype == CURLFILETYPE_FILE) {
    /* do not transfer files >= 50B */
    if(finfo->size > 50) {
      printf("SKIPPED\n");
      return CURL_CHUNK_BGN_FUNC_SKIP;
    }

    data->output = fopen(finfo->filename, "wb");
    if(!data->output) {
      return CURL_CHUNK_BGN_FUNC_FAIL;
    }
  }

  return CURL_CHUNK_BGN_FUNC_OK;
}

int main()
{
  /* data for callback */
  struct callback_data callback_info;

  CURL *curl = curl_easy_init();

  /* callback is called before download of concrete file started */
  curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
  curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &callback_info);
}

see how callback_info just vibes its way into file_is_coming as ptr, and then gets cast back to struct callback_data *data? that's the whole trick, iykyk. 🫢


⭐ AVAILABILITY ⭐

Added in curl 7.21.0 β€” a genuine vintage icon, honestly. πŸ•°οΈ


πŸ’… RETURN VALUE πŸ’…

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

  • CURLE_OK (0) means everything was OK ✨
  • non-zero means an error occurred 😭 β€” go check libcurl-errors(3) for the deets

πŸ“ SEE ALSO πŸ“


ngl bestie, this one is a "pass your own stuff through" option and nothing more. no hidden lore, no surprise behaviour, just a pointer and a dream. 🧚

with love, from the libcurl girlies β€” this page is dated 2026-10-12 and it ate, no crumbs. periodt. πŸ’œ

πŸ“¦ where this page comes from