examples: improve global init, error checks and returning errors

- add `curl_global_init()` and `curl_global_cleanup()` where missing.
- check the result of `curl_global_init()` where missing.
- return the last curl error from `main()`.
- drop Win32-specific socket initialization in favor of `curl_global_init()`.
- rename some outliers to `res` for curl result code.
- fix cleanup in some error cases.

Inspired by Joshua's report on examples.

Closes #19053
This commit is contained in:
Viktor Szakats 2025-10-13 16:30:18 +02:00
parent 3049c8e0a0
commit 4c7507daf9
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
129 changed files with 990 additions and 485 deletions

View file

@ -85,68 +85,72 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
int main(void)
{
CURL *curl;
CURLM *mcurl;
int still_running = 1;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx = { 0 };
curl_global_init(CURL_GLOBAL_DEFAULT);
CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
if(res)
return (int)res;
curl = curl_easy_init();
if(!curl)
return 1;
if(curl) {
CURLM *mcurl;
mcurl = curl_multi_init();
if(!mcurl)
return 2;
mcurl = curl_multi_init();
if(mcurl) {
int still_running = 1;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx = { 0 };
/* This is the URL for your mailserver */
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.com");
/* This is the URL for your mailserver */
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.com");
/* Note that this option is not strictly required, omitting it results in
* libcurl sending the MAIL FROM command with empty sender data. All
* autoresponses should have an empty reverse-path, and should be directed
* to the address in the reverse-path which triggered them. Otherwise, they
* could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_MAIL);
/* Note that this option is not strictly required, omitting it results
* in libcurl sending the MAIL FROM command with empty sender data. All
* autoresponses should have an empty reverse-path, and should be
* directed to the address in the reverse-path which triggered them.
* Otherwise, they could cause an endless loop. See RFC 5321 Section
* 4.5.5 for more details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_MAIL);
/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO_MAIL);
recipients = curl_slist_append(recipients, CC_MAIL);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO_MAIL);
recipients = curl_slist_append(recipients, CC_MAIL);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
/* We are using a callback function to specify the payload (the headers and
* body of the message). You could just use the CURLOPT_READDATA option to
* specify a FILE pointer to read from. */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* We are using a callback function to specify the payload (the headers
* and body of the message). You could just use the CURLOPT_READDATA
* option to specify a FILE pointer to read from. */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* Tell the multi stack about our easy handle */
curl_multi_add_handle(mcurl, curl);
/* Tell the multi stack about our easy handle */
curl_multi_add_handle(mcurl, curl);
do {
CURLMcode mc = curl_multi_perform(mcurl, &still_running);
do {
CURLMcode mc = curl_multi_perform(mcurl, &still_running);
if(still_running)
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
if(still_running)
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
if(mc)
break;
if(mc)
break;
} while(still_running);
} while(still_running);
/* Free the list of recipients */
curl_slist_free_all(recipients);
/* Free the list of recipients */
curl_slist_free_all(recipients);
/* Always cleanup */
curl_multi_remove_handle(mcurl, curl);
curl_multi_cleanup(mcurl);
}
curl_easy_cleanup(curl);
}
/* Always cleanup */
curl_multi_remove_handle(mcurl, curl);
curl_multi_cleanup(mcurl);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;