GHA/checkdocs: verify examples with picky warnings enables, also with clang

Verify example snippets with the picky warning options used when
compiling curl core code and standalone example code. Also test with
clang. Extract picky warnings available via a new, internal, CMake
option.

Also:
- fix issues found.
- tried reproducing #22638 in CI (specifically the casts for `%p`),
  turns out it needs apple clang 17, and no longer reproducing with
  apple clang 21.

Follow-up to 5c61e16869 #22638

Closes #22639
This commit is contained in:
Viktor Szakats 2026-08-22 18:20:05 +02:00
parent ce165cda4f
commit 513869744f
No known key found for this signature in database
61 changed files with 158 additions and 116 deletions

View file

@ -37,7 +37,12 @@ if(!@files || $files[0] eq "-h") {
}
sub testcompile {
my $rc = system('gcc -c test.c -I include -W -Wall -pedantic -Werror ' .
my $cc = defined $ENV{'CC'} ? $ENV{'CC'} : 'gcc';
my $cflags = '';
if(defined $ENV{'CFLAGS'}) {
$cflags .= ' ' . $ENV{'CFLAGS'};
}
my $rc = system($cc . ' -c test.c -I include -W -Wall -pedantic -Werror ' . $cflags . ' ' .
'-Wno-unused-parameter -Wno-unused-but-set-variable ' .
'-DCURL_ALLOW_OLD_MULTI_SOCKET -DCURL_DISABLE_DEPRECATION') >> 8;
return $rc;

View file

@ -131,5 +131,17 @@ jobs:
- name: 'verify synopsis'
run: .github/scripts/verify-synopsis.pl docs/libcurl/curl*.md
- name: 'verify examples'
run: .github/scripts/verify-examples.pl docs/libcurl/curl*.md docs/libcurl/opts/*.md
- name: 'verify examples (gcc)'
run: |
cmake -B bld-gcc -G Ninja -D_CURL_PREFILL=ON -DCURL_USE_LIBPSL=OFF -DCURL_WERROR=ON -D_CURL_SAVE_PICKY_OPTIONS=ON
export CFLAGS; CFLAGS="$(cat bld-gcc/picky-options.txt)"
echo "${CFLAGS}"
.github/scripts/verify-examples.pl docs/libcurl/curl*.md docs/libcurl/opts/*.md
- name: 'verify examples (clang)'
run: |
export CC=clang
cmake -B bld-clang -G Ninja -D_CURL_PREFILL=ON -DCURL_USE_LIBPSL=OFF -DCURL_WERROR=ON -D_CURL_SAVE_PICKY_OPTIONS=ON
export CFLAGS; CFLAGS="$(cat bld-clang/picky-options.txt)"
echo "${CFLAGS}"
.github/scripts/verify-examples.pl docs/libcurl/curl*.md docs/libcurl/opts/*.md

View file

@ -451,6 +451,9 @@ if(_picky_nocheck OR _picky)
string(REPLACE ";" " " _picky_tmp "${_picky_tmp}")
string(STRIP "${_picky_tmp}" _picky_tmp)
message(STATUS "Picky compiler options: ${_picky_tmp}")
if(_CURL_SAVE_PICKY_OPTIONS)
file(WRITE "${PROJECT_BINARY_DIR}/picky-options.txt" "${_picky_tmp}")
endif()
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "${_picky_nocheck}" "${_picky}")
# Apply to all feature checks

View file

@ -77,6 +77,8 @@ int main(void)
CURL *curl = curl_easy_init();
if(curl) {
unsigned int origin;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
@ -87,7 +89,7 @@ int main(void)
}
/* extract the normal headers + 1xx + trailers from the last request */
unsigned int origin = CURLH_HEADER | CURLH_1XX | CURLH_TRAILER;
origin = CURLH_HEADER | CURLH_1XX | CURLH_TRAILER;
while((h = curl_easy_nextheader(curl, origin, -1, prev))) {
printf("%s: %s\n", h->name, h->value);
prev = h;

View file

@ -43,7 +43,7 @@ int main(void)
{
const struct curl_easyoption *opt = curl_easy_option_by_name("URL");
if(opt) {
printf("This option wants CURLoption %x\n", (int)opt->id);
printf("This option wants CURLoption %x\n", (unsigned int)opt->id);
}
}
~~~

View file

@ -117,17 +117,17 @@ The maximum amount of bytes the server supports to receive in early data
# EXAMPLE
~~~c
CURLcode my_export_cb(CURL *handle,
void *userptr,
const char *session_key,
const unsigned char *shmac,
size_t shmac_len,
const unsigned char *sdata,
size_t sdata_len,
curl_off_t valid_until,
int ietf_tls_id,
const char *alpn,
size_t earlydata_max)
static CURLcode my_export_cb(CURL *handle,
void *userptr,
const char *session_key,
const unsigned char *shmac,
size_t shmac_len,
const unsigned char *sdata,
size_t sdata_len,
curl_off_t valid_until,
int ietf_tls_id,
const char *alpn,
size_t earlydata_max)
{
/* persist sdata */
return CURLE_OK;

View file

@ -49,6 +49,8 @@ already expired is silently discarded.
# EXAMPLE
~~~c
extern unsigned char *shmac, *sdata;
int main(void)
{
CURLSHcode sh;
@ -62,7 +64,6 @@ int main(void)
curl = curl_easy_init();
if(curl) {
extern unsigned char *shmac, *sdata;
size_t hlen = 4, slen = 5;
curl_easy_setopt(curl, CURLOPT_SHARE, share);

View file

@ -222,10 +222,10 @@ int main(void)
struct curl_httppost *post = NULL;
struct curl_httppost *last = NULL;
char namebuffer[] = "name buffer";
long namelength = strlen(namebuffer);
size_t namelength = strlen(namebuffer);
char buffer[] = "test buffer";
char htmlbuffer[] = "<HTML>test buffer</HTML>";
long htmlbufferlength = strlen(htmlbuffer);
size_t htmlbufferlength = strlen(htmlbuffer);
struct curl_forms forms[3];
char file1[] = "my-face.jpg";
char file2[] = "your-face.jpg";
@ -250,12 +250,12 @@ int main(void)
/* Add ptrname/ptrcontent section */
curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer,
CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH,
namelength, CURLFORM_END);
(long)namelength, CURLFORM_END);
/* Add name/ptrcontent/contenttype section */
curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole",
CURLFORM_PTRCONTENTS, htmlbuffer,
CURLFORM_CONTENTSLENGTH, htmlbufferlength,
CURLFORM_CONTENTSLENGTH, (long)htmlbufferlength,
CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);
/* Add simple file section */

View file

@ -51,13 +51,14 @@ This, because first then does libcurl known which actual read callback to use.
# EXAMPLE
~~~c
size_t print_httppost_callback(void *arg, const char *buf, size_t len)
static size_t print_httppost_callback(void *arg, const char *buf, size_t len)
{
fwrite(buf, len, 1, stdout);
*((size_t *)arg) += len;
return len;
}
size_t print_httppost(struct curl_httppost *post);
size_t print_httppost(struct curl_httppost *post)
{
size_t total_size = 0;

View file

@ -109,16 +109,16 @@ typedef enum {
~~~c
int main(void)
{
const curl_ssl_backend **list;
int i;
/* choose a specific backend */
curl_global_sslset(CURLSSLBACKEND_WOLFSSL, NULL, NULL);
/* list the available ones */
const curl_ssl_backend **list;
curl_global_sslset(CURLSSLBACKEND_NONE, NULL, &list);
for(i = 0; list[i]; i++)
printf("SSL backend #%d: '%s' (ID: %d)\n",
printf("SSL backend #%d: '%s' (ID: %u)\n",
i, list[i]->name, list[i]->id);
}
~~~

View file

@ -110,7 +110,7 @@ source to avoid data duplication. In this case, original data must be retained
until after the transfer terminates.
~~~c
#include <string.h> /* for memcpy */
char hugedata[512000];
static char hugedata[512000];
struct ctl {
char *buffer;
@ -118,7 +118,8 @@ struct ctl {
curl_off_t position;
};
size_t read_callback(char *buffer, size_t size, size_t nitems, void *arg)
static size_t read_callback(char *buffer, size_t size, size_t nitems,
void *arg)
{
struct ctl *p = (struct ctl *)arg;
size_t sz = (size_t)(p->size - p->position);
@ -132,7 +133,7 @@ size_t read_callback(char *buffer, size_t size, size_t nitems, void *arg)
return sz;
}
int seek_callback(void *arg, curl_off_t offset, int origin)
static int seek_callback(void *arg, curl_off_t offset, int origin)
{
struct ctl *p = (struct ctl *) arg;
@ -143,6 +144,8 @@ int seek_callback(void *arg, curl_off_t offset, int origin)
case SEEK_CUR:
offset += p->position;
break;
default:
break;
}
if(offset < 0)

View file

@ -48,8 +48,8 @@ setting *subparts* to NULL.
~~~c
static char *inline_html = "<title>example</title>";
static char *inline_text = "once upon the time";
static const char *inline_html = "<title>example</title>";
static const char *inline_text = "once upon the time";
int main(void)
{

View file

@ -269,7 +269,7 @@ A '%' symbol is written. No argument is converted.
# EXAMPLE
~~~c
const char *name = "John";
static const char *name = "John";
int main(void)
{

View file

@ -53,11 +53,11 @@ It is acceptable to call this function from your multi callback functions.
int main(void)
{
CURLM *multi = curl_multi_init();
int private = 123;
int private_data = 123;
curl_socket_t fd = 0; /* file descriptor to associate our data with */
/* make our struct pointer associated with socket fd */
CURLMcode mresult = curl_multi_assign(multi, fd, &private);
CURLMcode mresult = curl_multi_assign(multi, fd, &private_data);
if(mresult)
printf("error: %s\n", curl_multi_strerror(mresult));
}

View file

@ -56,11 +56,13 @@ int main(void)
CURL *curl = curl_easy_init();
if(curl) {
CURL **list;
/* add the transfer */
curl_multi_add_handle(multi, curl);
/* extract all added handles */
CURL **list = curl_multi_get_handles(multi);
list = curl_multi_get_handles(multi);
if(list) {
int i;

View file

@ -46,7 +46,7 @@ This function has no effect on curl_multi_wait(3) calls.
~~~c
extern int time_to_die(void);
extern int set_something_to_signal_thread_1_to_exit(void);
extern int decide_to_stop_thread1();
extern int decide_to_stop_thread1(void);
int main(void)
{

View file

@ -48,7 +48,7 @@ static int push_cb(CURL *parent,
struct curl_pushheaders *headers,
void *clientp)
{
int i = 0;
size_t i = 0;
char *field;
do {
field = curl_pushheader_bynum(headers, i);

View file

@ -46,7 +46,7 @@ string comparison functions. This function works on all platforms.
~~~c
int main(int argc, char *argv[])
{
const char *name = "compare";
static const char *name = "compare";
if(curl_strequal(name, argv[1]))
printf("Name and input matches\n");
}

View file

@ -49,7 +49,7 @@ string comparison functions. This function works on all platforms.
~~~c
int main(int argc, char *argv[])
{
const char *name = "compare";
static const char *name = "compare";
if(curl_strnequal(name, argv[1], 5))
printf("Name and input matches in the 5 first bytes\n");
}

View file

@ -152,7 +152,7 @@ static size_t writecb(char *buffer, size_t size, size_t nitems, void *p)
struct customdata *c = (struct customdata *)p;
const struct curl_ws_frame *m = curl_ws_meta(c->easy);
printf("flags: %x\n", m->flags);
printf("flags: %x\n", (unsigned int)m->flags);
return 0;
}

View file

@ -86,7 +86,7 @@ calls.
int main(void)
{
const char *buffer = "PAYLOAD";
static const char *buffer = "PAYLOAD";
size_t offset = 0;
CURLcode result = CURLE_OK;
CURL *curl = curl_easy_init();

View file

@ -66,7 +66,7 @@ Supports all flags documented in curl_ws_meta(3).
struct read_ctx {
CURL *easy;
char *message;
const char *message;
size_t msg_len;
size_t nsent;
};
@ -83,7 +83,7 @@ static size_t readcb(char *buf, size_t nitems, size_t buflen, void *p)
result = curl_ws_start_frame(ctx->easy, CURLWS_TEXT,
(curl_off_t)ctx->msg_len);
if(result != CURLE_OK) {
fprintf(stderr, "error starting frame: %d\n", result);
fprintf(stderr, "error starting frame: %d\n", (int)result);
return CURL_READFUNC_ABORT;
}
}

View file

@ -55,10 +55,10 @@ int main(void)
printf("No auth available, perhaps no 401?\n");
else {
printf("%s%s%s%s\n",
auth & CURLAUTH_BASIC ? "Basic " : "",
auth & CURLAUTH_DIGEST ? "Digest " : "",
auth & CURLAUTH_NEGOTIATE ? "Negotiate " : "",
auth % CURLAUTH_NTLM ? "NTLM " : "");
(unsigned long)auth & CURLAUTH_BASIC ? "Basic " : "",
(unsigned long)auth & CURLAUTH_DIGEST ? "Digest " : "",
(unsigned long)auth & CURLAUTH_NEGOTIATE ? "Negotiate " : "",
(unsigned long)auth & CURLAUTH_NTLM ? "NTLM " : "");
}
}
}

View file

@ -56,10 +56,10 @@ int main(void)
printf("No proxy auth available, perhaps no 407?\n");
else {
printf("%s%s%s%s\n",
auth & CURLAUTH_BASIC ? "Basic " : "",
auth & CURLAUTH_DIGEST ? "Digest " : "",
auth & CURLAUTH_NEGOTIATE ? "Negotiate " : "",
auth % CURLAUTH_NTLM ? "NTLM " : "");
(unsigned long)auth & CURLAUTH_BASIC ? "Basic " : "",
(unsigned long)auth & CURLAUTH_DIGEST ? "Digest " : "",
(unsigned long)auth & CURLAUTH_NEGOTIATE ? "Negotiate " : "",
(unsigned long)auth & CURLAUTH_NTLM ? "NTLM " : "");
}
}
}

View file

@ -127,7 +127,8 @@ https://github.com/curl/curl/issues/685
#include <curl/curl.h>
#include <openssl/ssl.h>
CURL *curl;
static CURL *curl;
static size_t wf(char *ptr, size_t size, size_t nmemb, void *stream)
{
const struct curl_tlssessioninfo *info = NULL;
@ -150,7 +151,7 @@ int main(int argc, char *argv[])
result = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
return result;
return (int)result;
}
~~~

View file

@ -49,12 +49,13 @@ NULL, which means that there is no block list.
# EXAMPLE
~~~c
static char *server_block_list[] =
static const char *server_block_list[] =
{
"Microsoft-IIS/6.0",
"nginx/0.8.54",
NULL
};
int main(void)
{
CURLM *m = curl_multi_init();

View file

@ -44,7 +44,7 @@ NULL, which means that there is no block list.
# EXAMPLE
~~~c
static char *site_block_list[] =
static const char *site_block_list[] =
{
"www.haxx.se",
"www.example.com:1234",

View file

@ -44,11 +44,11 @@ NULL
#include <string.h>
/* only allow pushes for filenames starting with "push-" */
int push_callback(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *clientp)
static int push_callback(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *clientp)
{
char *headp;
int *transfers = (int *)clientp;

View file

@ -105,11 +105,11 @@ NULL, no callback
#include <string.h>
/* only allow pushes for filenames starting with "push-" */
int push_callback(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *clientp)
static int push_callback(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *clientp)
{
char *headp;
int *transfers = (int *)clientp;

View file

@ -58,17 +58,18 @@ NULL
# EXAMPLE
~~~c
#include <stdint.h> /* for uintptr_t */
#include <string.h>
int main(void)
{
char *strpem = "PEMDATA"; /* strpem must point to a PEM string */
static const char *strpem = "PEMDATA"; /* must point to a PEM string */
CURL *curl = curl_easy_init();
if(curl) {
CURLcode result;
struct curl_blob blob;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
blob.data = strpem;
blob.data = (void *)(uintptr_t)(const void *)strpem; /* strip const */
blob.len = strlen(strpem);
blob.flags = CURL_BLOB_COPY;
curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob);

View file

@ -132,7 +132,7 @@ static long file_is_coming(struct curl_fileinfo *finfo,
return CURL_CHUNK_BGN_FUNC_OK;
}
int main()
int main(void)
{
/* data for callback */
struct callback_data callback_info;

View file

@ -81,7 +81,7 @@ static long file_is_coming(struct curl_fileinfo *finfo,
return CURL_CHUNK_BGN_FUNC_OK;
}
int main()
int main(void)
{
/* data for callback */
struct callback_data callback_info;

View file

@ -63,7 +63,7 @@ static long file_is_downloaded(void *ptr)
return CURL_CHUNK_END_FUNC_OK;
}
int main()
int main(void)
{
/* data for callback */
struct callback_data callback_info;

View file

@ -119,10 +119,10 @@ static void dump(const char *text,
unsigned int width = 0x10;
fprintf(stream, "%s, %lu bytes (0x%lx)\n",
text, (long)size, (long)size);
text, (unsigned long)size, (unsigned long)size);
for(i = 0; i < size; i += width) {
fprintf(stream, "%4.4lx: ", (long)i);
fprintf(stream, "%4.4lx: ", (unsigned long)i);
/* show hex to the left */
for(c = 0; c < width; c++) {
@ -134,7 +134,8 @@ static void dump(const char *text,
/* show data on the right */
for(c = 0; (c < width) && (i + c < size); c++) {
char x = (ptr[i + c] >= 0x20 && ptr[i + c] < 0x80) ? ptr[i + c] : '.';
char x = (ptr[i + c] >= 0x20 && ptr[i + c] < 0x80)
? (char)ptr[i + c] : '.';
fputc(x, stream);
}

View file

@ -88,8 +88,8 @@ int main(void)
{
CURL *curl = curl_easy_init();
const char *config = \
"ecl:AED+DQA87wAgACB/RuzUCsW3uBbSFI7mzD63TUXpI8sGDTnFTbFCDpa+" \
static const char *config =
"ecl:AED+DQA87wAgACB/RuzUCsW3uBbSFI7mzD63TUXpI8sGDTnFTbFCDpa+"
"CAAEAAEAAQANY292ZXIuZGVmby5pZQAA";
if(curl) {
CURLcode result;

View file

@ -86,7 +86,7 @@ int main(void)
show the more generic information from curl_easy_strerror instead. */
if(result != CURLE_OK) {
size_t len = strlen(errbuf);
fprintf(stderr, "\nlibcurl: (%d) ", result);
fprintf(stderr, "\nlibcurl: (%d) ", (int)result);
if(len)
fprintf(stderr, "%s%s", errbuf,
((errbuf[len - 1] != '\n') ? "\n" : ""));

View file

@ -51,7 +51,7 @@ NULL
~~~c
struct my_info {
int shoesize;
char *secret;
const char *secret;
};
static size_t header_callback(char *buffer, size_t size,

View file

@ -58,14 +58,14 @@ static CURLSTScode hsts_cb(CURL *easy, struct curl_hstsentry *sts,
int main(void)
{
CURL *curl = curl_easy_init();
struct MyData this;
struct MyData my_data;
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* pass pointer that gets passed in to the
CURLOPT_HSTSREADFUNCTION callback */
curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &this);
curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &my_data);
/* set HSTS read callback */
curl_easy_setopt(curl, CURLOPT_HSTSREADFUNCTION, hsts_cb);

View file

@ -51,14 +51,14 @@ struct MyData {
int main(void)
{
CURL *curl = curl_easy_init();
struct MyData this;
struct MyData my_data;
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* pass pointer that gets passed in to the
CURLOPT_HSTSWRITEFUNCTION callback */
curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &this);
curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &my_data);
result = curl_easy_perform(curl);
curl_easy_cleanup(curl);

View file

@ -57,6 +57,7 @@ NULL
~~~c
int main(void)
{
CURL *curl;
struct curl_httppost *formpost;
struct curl_httppost *lastptr;
@ -82,7 +83,7 @@ int main(void)
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
CURL *curl = curl_easy_init();
curl = curl_easy_init();
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

View file

@ -59,12 +59,13 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd,
return CURL_SOCKOPT_ALREADY_CONNECTED;
}
extern int sockfd; /* the already connected one */
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. */

View file

@ -107,12 +107,13 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd,
return CURL_SOCKOPT_ALREADY_CONNECTED;
}
extern int sockfd; /* the already connected one */
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");

View file

@ -87,7 +87,7 @@ int main(void)
CURLcode result = CURLE_OK;
CURL *curl = curl_easy_init();
if(curl) {
const char *data = "data to send";
static const char *data = "data to send";
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
@ -104,7 +104,7 @@ int main(void)
/* send an application/json POST */
curl = curl_easy_init();
if(curl) {
const char *json = "{\"name\": \"daniel\"}";
static const char *json = "{\"name\": \"daniel\"}";
struct curl_slist *slist1 = NULL;
slist1 = curl_slist_append(slist1, "Content-Type: application/json");
slist1 = curl_slist_append(slist1, "Accept: application/json");

View file

@ -52,7 +52,7 @@ int main(void)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode result;
const char *data = "data to send";
static const char *data = "data to send";
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");

View file

@ -50,11 +50,12 @@ NULL
~~~c
int main(void)
{
CURL *curl;
struct curl_slist *cmdlist = NULL;
cmdlist = curl_slist_append(cmdlist, "RNFR source-name");
cmdlist = curl_slist_append(cmdlist, "RNTO new-name");
CURL *curl = curl_easy_init();
curl = curl_easy_init();
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin");

View file

@ -52,10 +52,11 @@ NULL
~~~c
int main(void)
{
CURL *curl;
struct curl_slist *cmdlist = NULL;
cmdlist = curl_slist_append(cmdlist, "SYST");
CURL *curl = curl_easy_init();
curl = curl_easy_init();
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin");

View file

@ -41,25 +41,25 @@ NULL
# EXAMPLE
~~~c
struct private {
struct private_data {
void *custom;
};
int main(void)
{
CURL *curl = curl_easy_init();
struct private secrets;
struct private_data secrets;
if(curl) {
CURLcode result;
struct private *extracted;
struct private_data *extracted;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* store a pointer to our private struct */
/* store a pointer to our private_data struct */
curl_easy_setopt(curl, CURLOPT_PRIVATE, &secrets);
result = curl_easy_perform(curl);
/* we can extract the private pointer again too */
/* we can extract the private_data pointer again too */
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &extracted);
curl_easy_cleanup(curl);

View file

@ -39,7 +39,7 @@ NULL
~~~c
struct progress {
char *private;
char *private_data;
size_t size;
};
@ -50,7 +50,7 @@ static int progress_callback(void *clientp,
double ulnow)
{
struct progress *memory = clientp;
printf("private: %p\n", (void *)memory->private);
printf("private: %p\n", (void *)memory->private_data);
/* use the values */

View file

@ -85,7 +85,7 @@ NULL. libcurl has an internal progress meter. That is rarely wanted by users.
~~~c
struct progress {
char *private;
char *private_data;
size_t size;
};
@ -96,7 +96,7 @@ static int progress_callback(void *clientp,
double ulnow)
{
struct progress *memory = clientp;
printf("private: %p\n", (void *)memory->private);
printf("private: %p\n", (void *)memory->private_data);
/* use the values */

View file

@ -66,8 +66,8 @@ NULL
~~~c
extern char *certificateData; /* point to the data */
size_t filesize; /* size of the data */
static char *certificateData; /* point to the data */
static size_t filesize; /* size of the data */
int main(void)
{

View file

@ -141,11 +141,12 @@ NULL
~~~c
int main(void)
{
CURL *curl;
struct curl_slist *cmdlist = NULL;
cmdlist = curl_slist_append(cmdlist, "RNFR source-name");
cmdlist = curl_slist_append(cmdlist, "RNTO new-name");
CURL *curl = curl_easy_init();
curl = curl_easy_init();
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin");

View file

@ -55,14 +55,14 @@ struct MyData {
int main(void)
{
CURL *curl = curl_easy_init();
struct MyData this;
struct MyData my_data;
if(curl) {
CURLcode result;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* pass pointer that gets passed in to the
CURLOPT_READFUNCTION callback */
curl_easy_setopt(curl, CURLOPT_READDATA, &this);
curl_easy_setopt(curl, CURLOPT_READDATA, &my_data);
result = curl_easy_perform(curl);
curl_easy_cleanup(curl);

View file

@ -84,7 +84,8 @@ fread(3)
# EXAMPLE
~~~c
size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
static size_t read_callback(char *ptr, size_t size, size_t nmemb,
void *userdata)
{
FILE *readhere = (FILE *)userdata;
curl_off_t nread;

View file

@ -56,7 +56,8 @@ int main(void)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode result;
char *prev_id = "old"; /* previously retrieved RTSP session ID */
static const char *prev_id = "old"; /* previously retrieved
RTSP session ID */
curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/");
curl_easy_setopt(curl, CURLOPT_RTSP_SESSION_ID, prev_id);
result = curl_easy_perform(curl);

View file

@ -71,15 +71,16 @@ struct mine {
void *custom;
};
int hostkeycb(void *clientp, /* passed with CURLOPT_SSH_HOSTKEYDATA */
int keytype, /* CURLKHTYPE */
const char *key, /* host key to check */
size_t keylen) /* length of the key */
static int hostkeycb(void *clientp, /* passed with CURLOPT_SSH_HOSTKEYDATA */
int keytype, /* CURLKHTYPE */
const char *key, /* host key to check */
size_t keylen) /* length of the key */
{
/* 'clientp' points to the callback_data struct */
/* investigate the situation and return the correct value */
return CURLKHMATCH_OK;
}
int main(void)
{
struct mine callback_data;

View file

@ -84,7 +84,7 @@ int main(void)
CURL *curl;
CURLcode result;
/* CA cert in PEM format, replace the XXXs */
char *mypem =
const char *mypem =
"-----BEGIN CERTIFICATE-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"

View file

@ -144,7 +144,7 @@ int main(void)
CURL *curl;
CURLcode result;
/* CA cert in PEM format, replace the XXXs */
char *mypem =
const char *mypem =
"-----BEGIN CERTIFICATE-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"

View file

@ -41,7 +41,7 @@ CURLOPT_TFTP_BLKSIZE(3) is ignored.
# EXAMPLE
~~~c
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *fp)
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *fp)
{
return fwrite(ptr, size, nmemb, (FILE *)fp);
}

View file

@ -79,6 +79,7 @@ int main(void)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode result;
struct curl_slist *headers;
/* Set the URL of the request */
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
@ -89,8 +90,7 @@ int main(void)
Let that function be read_cb */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Trailer: My-super-awesome-trailer");
headers = curl_slist_append(NULL, "Trailer: My-super-awesome-trailer");
result = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
/* Set the trailers filling callback */

View file

@ -42,7 +42,7 @@ NULL
~~~c
struct progress {
char *private;
char *private_data;
size_t size;
};
@ -53,7 +53,7 @@ static int progress_cb(void *clientp,
curl_off_t ulnow)
{
struct progress *memory = clientp;
printf("private ptr: %p\n", (void *)memory->private);
printf("private ptr: %p\n", (void *)memory->private_data);
/* use the values */
return 0; /* all is good */

View file

@ -81,7 +81,7 @@ NULL - use the internal progress meter. That is rarely wanted by users.
~~~c
struct progress {
char *private;
char *private_data;
size_t size;
};
@ -92,7 +92,7 @@ static int xferinfo_callback(void *clientp,
curl_off_t ulnow)
{
struct progress *memory = clientp;
printf("my ptr: %p\n", (void *)memory->private);
printf("my ptr: %p\n", (void *)memory->private_data);
/* use the values */