examples: check more errors, fix cleanups, scope variables

Inspired by Joshua's report on examples.

Closes #19055
This commit is contained in:
Viktor Szakats 2025-10-13 22:57:01 +02:00
parent 61dcb56743
commit 64ed2ea196
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
42 changed files with 874 additions and 785 deletions

View file

@ -43,21 +43,17 @@
* Download an HTTP file and upload an FTP file simultaneously.
*/
#define HANDLECOUNT 2 /* Number of simultaneous transfers */
#define HTTP_HANDLE 0 /* Index for the HTTP transfer */
#define FTP_HANDLE 1 /* Index for the FTP transfer */
#define HANDLECOUNT 2 /* Number of simultaneous transfers */
int main(void)
{
CURL *handles[HANDLECOUNT];
CURLM *multi_handle;
int still_running = 0; /* keep number of running handles */
int i;
CURLMsg *msg; /* for picking up messages with the transfer status */
int msgs_left; /* how many messages are left */
CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
if(res)
return (int)res;
@ -74,124 +70,132 @@ int main(void)
/* init a multi stack */
multi_handle = curl_multi_init();
if(multi_handle) {
/* add the individual transfers */
for(i = 0; i < HANDLECOUNT; i++)
curl_multi_add_handle(multi_handle, handles[i]);
int still_running = 0; /* keep number of running handles */
/* we start some action by calling perform right away */
curl_multi_perform(multi_handle, &still_running);
CURLMsg *msg; /* for picking up messages with the transfer status */
int msgs_left; /* how many messages are left */
while(still_running) {
struct timeval timeout;
int rc; /* select() return code */
CURLMcode mc; /* curl_multi_fdset() return code */
/* add the individual transfers */
for(i = 0; i < HANDLECOUNT; i++)
curl_multi_add_handle(multi_handle, handles[i]);
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
/* we start some action by calling perform right away */
curl_multi_perform(multi_handle, &still_running);
long curl_timeo = -1;
while(still_running) {
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
struct timeval timeout;
int rc; /* select() return code */
CURLMcode mc; /* curl_multi_fdset() return code */
/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
curl_multi_timeout(multi_handle, &curl_timeo);
if(curl_timeo >= 0) {
long curl_timeo = -1;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
curl_multi_timeout(multi_handle, &curl_timeo);
if(curl_timeo >= 0) {
#if defined(MSDOS) || defined(__AMIGA__)
timeout.tv_sec = (time_t)(curl_timeo / 1000);
timeout.tv_sec = (time_t)(curl_timeo / 1000);
#else
timeout.tv_sec = curl_timeo / 1000;
timeout.tv_sec = curl_timeo / 1000;
#endif
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
#if defined(MSDOS) || defined(__AMIGA__)
timeout.tv_usec = (time_t)(curl_timeo % 1000) * 1000;
timeout.tv_usec = (time_t)(curl_timeo % 1000) * 1000;
#else
timeout.tv_usec = (int)(curl_timeo % 1000) * 1000;
timeout.tv_usec = (int)(curl_timeo % 1000) * 1000;
#endif
}
}
/* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK) {
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}
if(mc != CURLM_OK) {
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}
/* On success the value of maxfd is guaranteed to be >= -1. We call
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
to sleep 100ms, which is the minimum suggested value in the
curl_multi_fdset() doc. */
/* On success the value of maxfd is guaranteed to be >= -1. We call
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
to sleep 100ms, which is the minimum suggested value in the
curl_multi_fdset() doc. */
if(maxfd == -1) {
if(maxfd == -1) {
#ifdef _WIN32
Sleep(100);
rc = 0;
Sleep(100);
rc = 0;
#else
/* Portable sleep for platforms other than Windows. */
struct timeval wait = {0};
wait.tv_usec = 100 * 1000; /* 100ms */
rc = select(0, NULL, NULL, NULL, &wait);
/* Portable sleep for platforms other than Windows. */
struct timeval wait = {0};
wait.tv_usec = 100 * 1000; /* 100ms */
rc = select(0, NULL, NULL, NULL, &wait);
#endif
}
else {
/* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */
rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
}
else {
/* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */
rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
}
switch(rc) {
case -1:
/* select error */
break;
case 0: /* timeout */
default: /* action */
curl_multi_perform(multi_handle, &still_running);
break;
}
}
switch(rc) {
case -1:
/* select error */
break;
case 0: /* timeout */
default: /* action */
curl_multi_perform(multi_handle, &still_running);
break;
}
}
/* See how the transfers went */
/* !checksrc! disable EQUALSNULL 1 */
while((msg = curl_multi_info_read(multi_handle, &msgs_left)) != NULL) {
if(msg->msg == CURLMSG_DONE) {
int idx;
/* See how the transfers went */
/* !checksrc! disable EQUALSNULL 1 */
while((msg = curl_multi_info_read(multi_handle, &msgs_left)) != NULL) {
if(msg->msg == CURLMSG_DONE) {
int idx;
/* Find out which handle this message is about */
for(idx = 0; idx < HANDLECOUNT; idx++) {
int found = (msg->easy_handle == handles[idx]);
if(found)
break;
}
/* Find out which handle this message is about */
for(idx = 0; idx < HANDLECOUNT; idx++) {
int found = (msg->easy_handle == handles[idx]);
if(found)
switch(idx) {
case HTTP_HANDLE:
printf("HTTP transfer completed with status %d\n", msg->data.result);
break;
}
switch(idx) {
case HTTP_HANDLE:
printf("HTTP transfer completed with status %d\n", msg->data.result);
break;
case FTP_HANDLE:
printf("FTP transfer completed with status %d\n", msg->data.result);
break;
case FTP_HANDLE:
printf("FTP transfer completed with status %d\n", msg->data.result);
break;
}
}
}
}
curl_multi_cleanup(multi_handle);
curl_multi_cleanup(multi_handle);
}
/* Free the curl handles */
for(i = 0; i < HANDLECOUNT; i++)
curl_easy_cleanup(handles[i]);
curl_global_cleanup();
curl_global_cleanup();
return 0;
}