- add global init and deinit where missing.
- check global init success.
- improve cleaning up on error codepaths.
- drop `CLI_ERR()` macro, that could quit.
Also make error messages tell the reason.
Closes #19309
return realsize;
}
-#define CLI_ERR() \
- do { \
- curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n");\
- return (CURLcode)2; \
- } while(0)
-
static CURLcode test_cli_h2_pausing(const char *URL)
{
struct handle handles[2];
- CURLM *multi_handle;
+ CURLM *multi_handle = NULL;
int still_running = 1, msgs_left, numfds;
size_t i;
CURLMsg *msg;
int rounds = 0;
- CURLcode rc = CURLE_OK;
+ CURLcode result = CURLE_OK;
CURLU *cu;
struct curl_slist *resolve = NULL;
char resolve_buf[1024];
}
url = test_argv[0];
- curl_global_init(CURL_GLOBAL_DEFAULT);
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
+
curl_global_trace("ids,time,http/2,http/3");
+ memset(handles, 0, sizeof(handles));
+
cu = curl_url();
if(!cu) {
curl_mfprintf(stderr, "out of memory\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_set(cu, CURLUPART_URL, url, 0)) {
curl_mfprintf(stderr, "not a URL: '%s'\n", url);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) {
curl_mfprintf(stderr, "could not get host of '%s'\n", url);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) {
curl_mfprintf(stderr, "could not get port of '%s'\n", url);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
memset(&resolve, 0, sizeof(resolve));
curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1",
curl_easy_setopt(handles[i].h, CURLOPT_RESOLVE, resolve) != CURLE_OK ||
curl_easy_setopt(handles[i].h, CURLOPT_PIPEWAIT, 1L) ||
curl_easy_setopt(handles[i].h, CURLOPT_URL, url) != CURLE_OK) {
- CLI_ERR();
+ curl_mfprintf(stderr, "failed configuring easy handle - bailing out\n");
+ result = (CURLcode)2;
+ goto cleanup;
}
curl_easy_setopt(handles[i].h, CURLOPT_HTTP_VERSION, http_version);
}
multi_handle = curl_multi_init();
- if(!multi_handle)
- CLI_ERR();
+ if(!multi_handle) {
+ curl_mfprintf(stderr, "curl_multi_init() failed - bailing out\n");
+ result = (CURLcode)2;
+ goto cleanup;
+ }
for(i = 0; i < CURL_ARRAYSIZE(handles); i++) {
- if(curl_multi_add_handle(multi_handle, handles[i].h) != CURLM_OK)
- CLI_ERR();
+ if(curl_multi_add_handle(multi_handle, handles[i].h) != CURLM_OK) {
+ curl_mfprintf(stderr, "curl_multi_add_handle() failed - bailing out\n");
+ result = (CURLcode)2;
+ goto cleanup;
+ }
}
for(rounds = 0;; rounds++) {
curl_mfprintf(stderr, "INFO: multi_perform round %d\n", rounds);
- if(curl_multi_perform(multi_handle, &still_running) != CURLM_OK)
- CLI_ERR();
+ if(curl_multi_perform(multi_handle, &still_running) != CURLM_OK) {
+ curl_mfprintf(stderr, "curl_multi_perform() failed - bailing out\n");
+ result = (CURLcode)2;
+ goto cleanup;
+ }
if(!still_running) {
int as_expected = 1;
if(!as_expected) {
curl_mfprintf(stderr, "ERROR: handles not in expected state "
"after %d rounds\n", rounds);
- rc = (CURLcode)1;
+ result = (CURLcode)1;
}
break;
}
- if(curl_multi_poll(multi_handle, NULL, 0, 100, &numfds) != CURLM_OK)
- CLI_ERR();
+ if(curl_multi_poll(multi_handle, NULL, 0, 100, &numfds) != CURLM_OK) {
+ curl_mfprintf(stderr, "curl_multi_poll() failed - bailing out\n");
+ result = (CURLcode)2;
+ goto cleanup;
+ }
/* !checksrc! disable EQUALSNULL 1 */
while((msg = curl_multi_info_read(multi_handle, &msgs_left)) != NULL) {
"resumed=%d, result %d - wtf?\n", i,
handles[i].paused,
handles[i].resumed, msg->data.result);
- rc = (CURLcode)1;
- goto out;
+ result = (CURLcode)1;
+ goto cleanup;
}
}
}
}
}
-out:
+cleanup:
+
for(i = 0; i < CURL_ARRAYSIZE(handles); i++) {
curl_multi_remove_handle(multi_handle, handles[i].h);
curl_easy_cleanup(handles[i].h);
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
- return rc;
+ return result;
}
#include "testtrace.h"
#include "memdebug.h"
-static FILE *out_download;
+static FILE *out_download = NULL;
static int setup_h2_serverpush(CURL *hnd, const char *url)
{
return 0; /* all is good */
}
-static FILE *out_push;
+static FILE *out_push = NULL;
/* called when there is an incoming push */
static int server_push_callback(CURL *parent,
*/
static CURLcode test_cli_h2_serverpush(const char *URL)
{
- CURL *easy;
+ CURL *easy = NULL;
CURLM *multi_handle;
int transfers = 1; /* we start with one */
+ CURLcode result = CURLE_OK;
debug_config.nohex = TRUE;
debug_config.tracetime = FALSE;
return (CURLcode)2;
}
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
+
multi_handle = curl_multi_init();
+ if(!multi_handle) {
+ result = (CURLcode)1;
+ goto cleanup;
+ }
easy = curl_easy_init();
+ if(!easy) {
+ result = (CURLcode)1;
+ goto cleanup;
+ }
+
if(setup_h2_serverpush(easy, URL)) {
- curlx_fclose(out_download);
curl_mfprintf(stderr, "failed\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
} while(transfers); /* as long as we have transfers going */
+cleanup:
+
curl_multi_cleanup(multi_handle);
- curlx_fclose(out_download);
+ if(out_download)
+ curlx_fclose(out_download);
if(out_push)
curlx_fclose(out_push);
- return CURLE_OK;
+ curl_global_cleanup();
+
+ return result;
}
CURLMsg *msg;
int msgs_in_queue;
char range[128];
- CURLcode exitcode = (CURLcode)1;
+ CURLcode result = (CURLcode)1;
if(!URL) {
curl_mfprintf(stderr, "need URL as argument\n");
return (CURLcode)2;
}
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
+
multi = curl_multi_init();
if(!multi) {
curl_mfprintf(stderr, "curl_multi_init failed\n");
} while(running_handles > 0 || start_count);
curl_mfprintf(stderr, "exiting\n");
- exitcode = CURLE_OK;
+ result = CURLE_OK;
cleanup:
curl_multi_cleanup(multi);
}
- return exitcode;
+ curl_global_cleanup();
+
+ return result;
}
*/
static CURLcode test_cli_hx_download(const char *URL)
{
- CURLM *multi_handle;
+ CURLM *multi_handle = NULL;
struct CURLMsg *m;
- CURLSH *share;
+ CURLSH *share = NULL;
const char *url;
size_t i, n, max_parallel = 1;
size_t active_transfers;
size_t abort_offset = 0;
size_t fail_offset = 0;
int abort_paused = 0, use_earlydata = 0;
- struct transfer_d *t;
+ struct transfer_d *t = NULL;
long http_version = CURL_HTTP_VERSION_2_0;
int ch;
struct curl_slist *host = NULL;
case 'h':
usage_hx_download(NULL);
result = (CURLcode)2;
- goto cleanup;
+ goto optcleanup;
case 'a':
abort_paused = 1;
break;
else {
usage_hx_download("invalid http version");
result = (CURLcode)1;
- goto cleanup;
+ goto optcleanup;
}
break;
}
default:
usage_hx_download("invalid option");
result = (CURLcode)1;
- goto cleanup;
+ goto optcleanup;
}
}
test_argc -= coptind;
test_argv += coptind;
- curl_global_init(CURL_GLOBAL_DEFAULT);
curl_global_trace("ids,time,http/2,http/3");
if(test_argc != 1) {
usage_hx_download("not enough arguments");
result = (CURLcode)2;
- goto cleanup;
+ goto optcleanup;
}
url = test_argv[0];
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ result = (CURLcode)3;
+ goto optcleanup;
+ }
+
if(resolve)
host = curl_slist_append(NULL, resolve);
} while(active_transfers); /* as long as we have transfers going */
+cleanup:
+
curl_multi_cleanup(multi_handle);
- for(i = 0; i < transfer_count_d; ++i) {
- t = &transfer_d[i];
- if(t->out) {
- curlx_fclose(t->out);
- t->out = NULL;
- }
- if(t->easy) {
- curl_easy_cleanup(t->easy);
- t->easy = NULL;
+ if(transfer_d) {
+ for(i = 0; i < transfer_count_d; ++i) {
+ t = &transfer_d[i];
+ if(t->out) {
+ curlx_fclose(t->out);
+ t->out = NULL;
+ }
+ if(t->easy) {
+ curl_easy_cleanup(t->easy);
+ t->easy = NULL;
+ }
+ if(t->result)
+ result = t->result;
+ else /* on success we expect ssl to have been checked */
+ assert(t->checked_ssl);
}
- if(t->result)
- result = t->result;
- else /* on success we expect ssl to have been checked */
- assert(t->checked_ssl);
+ free(transfer_d);
}
- free(transfer_d);
curl_share_cleanup(share);
curl_slist_free_all(host);
-cleanup:
+
+ curl_global_cleanup();
+
+optcleanup:
+
free(resolve);
return result;
int reuse_easy = 0;
int use_earlydata = 0;
int announce_length = 0;
- struct transfer_u *t;
+ struct transfer_u *t = NULL;
long http_version = CURL_HTTP_VERSION_2_0;
struct curl_slist *host = NULL;
const char *resolve = NULL;
int ch;
+ CURLcode result = CURLE_OK;
(void)URL;
return (CURLcode)2;
}
- curl_global_init(CURL_GLOBAL_DEFAULT);
- curl_global_trace("ids,time,http/2,http/3");
-
if(test_argc != 1) {
usage_hx_upload("not enough arguments");
return (CURLcode)2;
}
url = test_argv[0];
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
+
+ curl_global_trace("ids,time,http/2,http/3");
+
if(resolve)
host = curl_slist_append(NULL, resolve);
share = curl_share_init();
if(!share) {
curl_mfprintf(stderr, "error allocating share\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
transfer_u = calloc(transfer_count_u, sizeof(*transfer_u));
if(!transfer_u) {
curl_mfprintf(stderr, "error allocating transfer structs\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
active_transfers = 0;
if(reuse_easy) {
CURL *easy = curl_easy_init();
- CURLcode rc = CURLE_OK;
if(!easy) {
curl_mfprintf(stderr, "failed to init easy handle\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
for(i = 0; i < transfer_count_u; ++i) {
+ CURLcode rc;
t = &transfer_u[i];
t->easy = easy;
if(setup_hx_upload(t->easy, url, t, http_version, host, share,
use_earlydata, announce_length)) {
curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
curl_mfprintf(stderr, "[t-%zu] STARTING\n", t->idx);
if(!t->easy || setup_hx_upload(t->easy, url, t, http_version, host,
share, use_earlydata, announce_length)) {
curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
curl_multi_add_handle(multi_handle, t->easy);
t->started = 1;
host, share, use_earlydata,
announce_length)) {
curl_mfprintf(stderr, "[t-%zu] FAILED setup\n", i);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
curl_multi_add_handle(multi_handle, t->easy);
t->started = 1;
curl_multi_cleanup(multi_handle);
}
- for(i = 0; i < transfer_count_u; ++i) {
- t = &transfer_u[i];
- if(t->out) {
- curlx_fclose(t->out);
- t->out = NULL;
- }
- if(t->easy) {
- curl_easy_cleanup(t->easy);
- t->easy = NULL;
- }
- if(t->mime) {
- curl_mime_free(t->mime);
+cleanup:
+
+ if(transfer_u) {
+ for(i = 0; i < transfer_count_u; ++i) {
+ t = &transfer_u[i];
+ if(t->out) {
+ curlx_fclose(t->out);
+ t->out = NULL;
+ }
+ if(t->easy) {
+ curl_easy_cleanup(t->easy);
+ t->easy = NULL;
+ }
+ if(t->mime) {
+ curl_mime_free(t->mime);
+ }
}
+ free(transfer_u);
}
- free(transfer_u);
+
curl_share_cleanup(share);
curl_slist_free_all(host);
+ curl_global_cleanup();
- return CURLE_OK;
+ return result;
}
int add_more, waits, ongoing = 0;
char *host = NULL, *port = NULL;
long http_version = CURL_HTTP_VERSION_1_1;
- CURLcode exitcode = (CURLcode)1;
+ CURLcode result = (CURLcode)1;
if(!URL || !libtest_arg2) {
curl_mfprintf(stderr, "need args: URL proto\n");
return (CURLcode)2;
}
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
+
if(!strcmp("h2", libtest_arg2))
http_version = CURL_HTTP_VERSION_2;
else if(!strcmp("h3", libtest_arg2))
cu = curl_url();
if(!cu) {
curl_mfprintf(stderr, "out of memory\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_set(cu, CURLUPART_URL, URL, 0)) {
curl_mfprintf(stderr, "not a URL: '%s'\n", URL);
if(!tse_found_tls_session) {
curl_mfprintf(stderr, "CURLINFO_TLS_SSL_PTR not found during run\n");
- exitcode = CURLE_FAILED_INIT;
+ result = CURLE_FAILED_INIT;
goto cleanup;
}
curl_mfprintf(stderr, "exiting\n");
- exitcode = CURLE_OK;
+ result = CURLE_OK;
cleanup:
curl_slist_free_all(resolve);
curl_free(host);
curl_free(port);
- curl_url_cleanup(cu);
+ if(cu)
+ curl_url_cleanup(cu);
+ curl_global_cleanup();
- return exitcode;
+ return result;
}
static CURLcode test_cli_upload_pausing(const char *URL)
{
- CURL *curl;
- CURLcode rc = CURLE_OK;
+ CURL *curl = NULL;
+ CURLcode result = CURLE_OK;
CURLU *cu;
struct curl_slist *resolve = NULL;
char resolve_buf[1024];
}
url = test_argv[0];
- curl_global_init(CURL_GLOBAL_DEFAULT);
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
+
curl_global_trace("ids,time");
cu = curl_url();
if(!cu) {
curl_mfprintf(stderr, "out of memory\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_set(cu, CURLUPART_URL, url, 0)) {
curl_mfprintf(stderr, "not a URL: '%s'\n", url);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) {
curl_mfprintf(stderr, "could not get host of '%s'\n", url);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) {
curl_mfprintf(stderr, "could not get port of '%s'\n", url);
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
memset(&resolve, 0, sizeof(resolve));
curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1",
curl = curl_easy_init();
if(!curl) {
curl_mfprintf(stderr, "out of memory\n");
- return (CURLcode)1;
+ result = (CURLcode)1;
+ goto cleanup;
}
/* We want to use our own read function. */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, cli_debug_cb) != CURLE_OK ||
curl_easy_setopt(curl, CURLOPT_RESOLVE, resolve) != CURLE_OK) {
curl_mfprintf(stderr, "something unexpected went wrong - bailing out!\n");
- return (CURLcode)2;
+ result = (CURLcode)2;
+ goto cleanup;
}
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version);
- rc = curl_easy_perform(curl);
+ result = curl_easy_perform(curl);
- if(curl) {
- curl_easy_cleanup(curl);
- }
+cleanup:
+ if(curl)
+ curl_easy_cleanup(curl);
curl_slist_free_all(resolve);
curl_free(host);
curl_free(port);
- curl_url_cleanup(cu);
+ if(cu)
+ curl_url_cleanup(cu);
curl_global_cleanup();
- return rc;
+ return result;
}
static CURLcode test_cli_ws_data(const char *URL)
{
#ifndef CURL_DISABLE_WEBSOCKETS
- CURLcode res = CURLE_OK;
+ CURLcode result = CURLE_OK;
const char *url;
size_t plen_min = 0, plen_max = 0, count = 1;
int ch, model = 2;
break;
case 'h':
test_ws_data_usage(NULL);
- res = CURLE_BAD_FUNCTION_ARGUMENT;
- goto cleanup;
+ return CURLE_BAD_FUNCTION_ARGUMENT;
case 'c':
count = (size_t)atol(coptarg);
break;
break;
default:
test_ws_data_usage("invalid option");
- res = CURLE_BAD_FUNCTION_ARGUMENT;
- goto cleanup;
+ return CURLE_BAD_FUNCTION_ARGUMENT;
}
}
test_argc -= coptind;
if(plen_max < plen_min) {
curl_mfprintf(stderr, "maxlen must be >= minlen, got %zu-%zu\n",
plen_min, plen_max);
- res = CURLE_BAD_FUNCTION_ARGUMENT;
- goto cleanup;
+ return CURLE_BAD_FUNCTION_ARGUMENT;
}
if(test_argc != 1) {
test_ws_data_usage(NULL);
- res = CURLE_BAD_FUNCTION_ARGUMENT;
- goto cleanup;
+ return CURLE_BAD_FUNCTION_ARGUMENT;
}
url = test_argv[0];
- curl_global_init(CURL_GLOBAL_ALL);
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
if(model == 1)
- res = test_ws_data_m1_echo(url, plen_min, plen_max);
+ result = test_ws_data_m1_echo(url, plen_min, plen_max);
else
- res = test_ws_data_m2_echo(url, count, plen_min, plen_max);
+ result = test_ws_data_m2_echo(url, count, plen_min, plen_max);
-cleanup:
curl_global_cleanup();
- return res;
+
+ return result;
#else /* !CURL_DISABLE_WEBSOCKETS */
(void)URL;
{
#ifndef CURL_DISABLE_WEBSOCKETS
CURL *curl;
- CURLcode res = CURLE_OK;
+ CURLcode result = CURLE_OK;
const char *payload;
if(!URL || !libtest_arg2) {
}
payload = libtest_arg2;
- curl_global_init(CURL_GLOBAL_ALL);
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return (CURLcode)3;
+ }
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_USERAGENT, "ws-pingpong");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); /* websocket style */
- res = curl_easy_perform(curl);
- curl_mfprintf(stderr, "curl_easy_perform() returned %u\n", res);
- if(res == CURLE_OK)
- res = pingpong(curl, payload);
+ result = curl_easy_perform(curl);
+ curl_mfprintf(stderr, "curl_easy_perform() returned %u\n", result);
+ if(result == CURLE_OK)
+ result = pingpong(curl, payload);
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
- return res;
+ return result;
#else /* !CURL_DISABLE_WEBSOCKETS */
(void)URL;