From: Viktor Szakats Date: Thu, 27 Feb 2025 10:32:43 +0000 (+0100) Subject: tidy-up: prefer `return` over `exit()`, fix fallouts X-Git-Tag: curl-8_13_0~318 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=08c7c937dc0dbd1f92f73360e5d8b2bb2ee6afa8;p=thirdparty%2Fcurl.git tidy-up: prefer `return` over `exit()`, fix fallouts To avoid breaking the control flow and align to majority of code already using `return`. `exit()` has the side-effect of suppressing leak detection in cases. Fix fallouts detected after switching to `return`. - configure: - fix `getaddrinfo` run test to call `freeaddrinfo()` to pacify ASAN, and call `WSACleanup()` to deinit winsock2. - fix `getifaddrs` run test to call `freeifaddrs()` to pacify ASAN. - tests/server: - setup `atexit(win32_cleanup)` via `win32_init()`. - return 2 instead of 1 on winsock2 init failures. - sws: goto cleanup instead of `exit()` in `http_connect()`. Follow-up to 02dfe7193704817184b522888ffa926e6b73f648 #7235 - tests/client/http: - cleanup memory to pacify ASAN in `h2-upgrade-extreme`, `tls-session-reuse`. - examples: - block_ip: fix memory leak reported by CI. - http2-upload: avoid handle leaks. Untouched `exit()` calls, made from callbacks: - docs/examples: ephiperfifo.c, ghiper.c, hiperfifo.c - tests/libtest: lib582.c, lib655.c, lib670.c - tests/server: tftpd.c Closes #16507 --- diff --git a/docs/examples/block_ip.c b/docs/examples/block_ip.c index b185177ab6..9a1c0222e8 100644 --- a/docs/examples/block_ip.c +++ b/docs/examples/block_ip.c @@ -298,14 +298,19 @@ int main(void) filter = (struct connection_filter *)calloc(1, sizeof(*filter)); if(!filter) - exit(1); + return 1; - if(curl_global_init(CURL_GLOBAL_DEFAULT)) - exit(1); + if(curl_global_init(CURL_GLOBAL_DEFAULT)) { + free(filter); + return 1; + } curl = curl_easy_init(); - if(!curl) - exit(1); + if(!curl) { + curl_global_cleanup(); + free(filter); + return 1; + } /* Set the target URL */ curl_easy_setopt(curl, CURLOPT_URL, "http://localhost"); diff --git a/docs/examples/chkspeed.c b/docs/examples/chkspeed.c index 687b264b9b..fc40814696 100644 --- a/docs/examples/chkspeed.c +++ b/docs/examples/chkspeed.c @@ -79,12 +79,12 @@ int main(int argc, char *argv[]) fprintf(stderr, "\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n", appname); - exit(1); + return 1; case 'v': case 'V': fprintf(stderr, "\r%s %s - %s\n", appname, CHKSPEED_VERSION, curl_version()); - exit(1); + return 1; case 'a': case 'A': prtall = 1; diff --git a/docs/examples/cookie_interface.c b/docs/examples/cookie_interface.c index 396aeca97e..da40953d91 100644 --- a/docs/examples/cookie_interface.c +++ b/docs/examples/cookie_interface.c @@ -34,8 +34,7 @@ #include #include -static void -print_cookies(CURL *curl) +static int print_cookies(CURL *curl) { CURLcode res; struct curl_slist *cookies; @@ -47,7 +46,7 @@ print_cookies(CURL *curl) if(res != CURLE_OK) { fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res)); - exit(1); + return 1; } nc = cookies; i = 1; @@ -60,6 +59,8 @@ print_cookies(CURL *curl) printf("(none)\n"); } curl_slist_free_all(cookies); + + return 0; } int diff --git a/docs/examples/htmltitle.cpp b/docs/examples/htmltitle.cpp index f8a463a788..52dbdf1535 100644 --- a/docs/examples/htmltitle.cpp +++ b/docs/examples/htmltitle.cpp @@ -94,7 +94,7 @@ static bool init(CURL *&conn, const char *url) if(conn == NULL) { fprintf(stderr, "Failed to create CURL connection\n"); - exit(EXIT_FAILURE); + return false; } code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer); @@ -270,7 +270,7 @@ int main(int argc, char *argv[]) if(argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); - exit(EXIT_FAILURE); + return EXIT_FAILURE; } curl_global_init(CURL_GLOBAL_DEFAULT); @@ -279,7 +279,7 @@ int main(int argc, char *argv[]) if(!init(conn, argv[1])) { fprintf(stderr, "Connection initialization failed\n"); - exit(EXIT_FAILURE); + return EXIT_FAILURE; } // Retrieve content for the URL @@ -289,7 +289,7 @@ int main(int argc, char *argv[]) if(code != CURLE_OK) { fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer); - exit(EXIT_FAILURE); + return EXIT_FAILURE; } // Parse the (assumed) HTML code diff --git a/docs/examples/http2-download.c b/docs/examples/http2-download.c index 693f393ada..4a249fa979 100644 --- a/docs/examples/http2-download.c +++ b/docs/examples/http2-download.c @@ -142,7 +142,7 @@ int my_trace(CURL *handle, curl_infotype type, return 0; } -static void setup(struct transfer *t, int num) +static int setup(struct transfer *t, int num) { char filename[128]; CURL *hnd; @@ -155,7 +155,7 @@ static void setup(struct transfer *t, int num) if(!t->out) { fprintf(stderr, "error: could not open file %s for writing: %s\n", filename, strerror(errno)); - exit(1); + return 1; } /* write to this file */ @@ -179,6 +179,7 @@ static void setup(struct transfer *t, int num) /* wait for pipe connection to confirm */ curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L); #endif + return 0; } /* @@ -204,7 +205,8 @@ int main(int argc, char **argv) multi_handle = curl_multi_init(); for(i = 0; i < num_transfers; i++) { - setup(&trans[i], i); + if(setup(&trans[i], i)) + return 1; /* add the individual transfer */ curl_multi_add_handle(multi_handle, trans[i].easy); diff --git a/docs/examples/http2-upload.c b/docs/examples/http2-upload.c index 88a1bdbabd..580944f271 100644 --- a/docs/examples/http2-upload.c +++ b/docs/examples/http2-upload.c @@ -200,7 +200,7 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp) return retcode; } -static void setup(struct input *i, int num, const char *upload) +static int setup(struct input *i, int num, const char *upload) { FILE *out; char url[256]; @@ -209,14 +209,15 @@ static void setup(struct input *i, int num, const char *upload) curl_off_t uploadsize; CURL *hnd; - hnd = i->hnd = curl_easy_init(); + hnd = i->hnd = NULL; + i->num = num; curl_msnprintf(filename, 128, "dl-%d", num); out = fopen(filename, "wb"); if(!out) { fprintf(stderr, "error: could not open file %s for writing: %s\n", upload, strerror(errno)); - exit(1); + return 1; } curl_msnprintf(url, 256, "https://localhost:8443/upload-%d", num); @@ -225,7 +226,8 @@ static void setup(struct input *i, int num, const char *upload) if(stat(upload, &file_info)) { fprintf(stderr, "error: could not stat file %s: %s\n", upload, strerror(errno)); - exit(1); + fclose(out); + return 1; } uploadsize = file_info.st_size; @@ -234,9 +236,12 @@ static void setup(struct input *i, int num, const char *upload) if(!i->in) { fprintf(stderr, "error: could not open file %s for reading: %s\n", upload, strerror(errno)); - exit(1); + fclose(out); + return 1; } + hnd = i->hnd = curl_easy_init(); + /* write to this file */ curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out); @@ -269,6 +274,7 @@ static void setup(struct input *i, int num, const char *upload) /* wait for pipe connection to confirm */ curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L); #endif + return 0; } /* @@ -301,7 +307,8 @@ int main(int argc, char **argv) multi_handle = curl_multi_init(); for(i = 0; i < num_transfers; i++) { - setup(&trans[i], i, filename); + if(setup(&trans[i], i, filename)) + return 1; /* add the individual transfer */ curl_multi_add_handle(multi_handle, trans[i].hnd); diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4 index 6456c3e576..cce8025e4d 100644 --- a/m4/curl-compilers.m4 +++ b/m4/curl-compilers.m4 @@ -482,7 +482,7 @@ AC_DEFUN([CURL_COMPILER_WORKS_IFELSE], [ #endif ]],[[ int i = 0; - exit(i); + return i; ]]) ],[ tmp_compiler_works="yes" diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4 index 82bf39a306..fe55cb922a 100644 --- a/m4/curl-functions.m4 +++ b/m4/curl-functions.m4 @@ -1270,11 +1270,12 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [ struct addrinfo hints; struct addrinfo *ai = 0; int error; + int exitcode; #ifdef _WIN32 WSADATA wsa; if(WSAStartup(MAKEWORD(2, 2), &wsa)) - exit(2); + return 2; #endif memset(&hints, 0, sizeof(hints)); @@ -1283,9 +1284,15 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [ hints.ai_socktype = SOCK_STREAM; error = getaddrinfo("127.0.0.1", 0, &hints, &ai); if(error || !ai) - exit(1); /* fail */ - else - exit(0); + exitcode = 1; /* fail */ + else { + freeaddrinfo(ai); + exitcode = 0; + } + #ifdef _WIN32 + WSACleanup(); + #endif + return exitcode; ]]) ],[ AC_MSG_RESULT([yes]) @@ -1883,9 +1890,11 @@ AC_DEFUN([CURL_CHECK_FUNC_GETIFADDRS], [ error = getifaddrs(&ifa); if(error || !ifa) - exit(1); /* fail */ - else - exit(0); + return 1; /* fail */ + else { + freeifaddrs(ifa); + return 0; + } ]]) ],[ AC_MSG_RESULT([yes]) @@ -2003,9 +2012,9 @@ AC_DEFUN([CURL_CHECK_FUNC_GMTIME_R], [ gmt = gmtime_r(&local, &result); (void)result; if(gmt) - exit(0); + return 0; else - exit(1); + return 1; ]]) ],[ AC_MSG_RESULT([yes]) @@ -2134,13 +2143,13 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_NTOP], [ /* - */ ipv4ptr = inet_ntop(AF_INET, ipv4a, ipv4res, sizeof(ipv4res)); if(!ipv4ptr) - exit(1); /* fail */ + return 1; /* fail */ if(ipv4ptr != ipv4res) - exit(1); /* fail */ + return 1; /* fail */ if(!ipv4ptr[0]) - exit(1); /* fail */ + return 1; /* fail */ if(memcmp(ipv4res, "192.168.100.1", 13) != 0) - exit(1); /* fail */ + return 1; /* fail */ /* - */ ipv6res[0] = '\0'; memset(ipv6a, 0, sizeof(ipv6a)); @@ -2158,15 +2167,15 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_NTOP], [ /* - */ ipv6ptr = inet_ntop(AF_INET6, ipv6a, ipv6res, sizeof(ipv6res)); if(!ipv6ptr) - exit(1); /* fail */ + return 1; /* fail */ if(ipv6ptr != ipv6res) - exit(1); /* fail */ + return 1; /* fail */ if(!ipv6ptr[0]) - exit(1); /* fail */ + return 1; /* fail */ if(memcmp(ipv6res, "fe80::214:4fff:fe0b:76c8", 24) != 0) - exit(1); /* fail */ + return 1; /* fail */ /* - */ - exit(0); + return 0; ]]) ],[ AC_MSG_RESULT([yes]) @@ -2286,18 +2295,18 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_PTON], [ /* - */ memset(ipv4a, 1, sizeof(ipv4a)); if(1 != inet_pton(AF_INET, ipv4src, ipv4a)) - exit(1); /* fail */ + return 1; /* fail */ /* - */ if( (ipv4a[0] != 0xc0) || (ipv4a[1] != 0xa8) || (ipv4a[2] != 0x64) || (ipv4a[3] != 0x01) || (ipv4a[4] != 0x01) ) - exit(1); /* fail */ + return 1; /* fail */ /* - */ memset(ipv6a, 1, sizeof(ipv6a)); if(1 != inet_pton(AF_INET6, ipv6src, ipv6a)) - exit(1); /* fail */ + return 1; /* fail */ /* - */ if( (ipv6a[0] != 0xfe) || (ipv6a[1] != 0x80) || @@ -2310,7 +2319,7 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_PTON], [ (ipv6a[14] != 0x76) || (ipv6a[15] != 0xc8) || (ipv6a[16] != 0x01) ) - exit(1); /* fail */ + return 1; /* fail */ /* - */ if( (ipv6a[2] != 0x0) || (ipv6a[3] != 0x0) || @@ -2318,9 +2327,9 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_PTON], [ (ipv6a[5] != 0x0) || (ipv6a[6] != 0x0) || (ipv6a[7] != 0x0) ) - exit(1); /* fail */ + return 1; /* fail */ /* - */ - exit(0); + return 0; ]]) ],[ AC_MSG_RESULT([yes]) @@ -3809,11 +3818,11 @@ AC_DEFUN([CURL_CHECK_FUNC_STRERROR_R], [ buffer[0] = '\0'; string = strerror_r(EACCES, buffer, sizeof(buffer)); if(!string) - exit(1); /* fail */ + return 1; /* fail */ if(!string[0]) - exit(1); /* fail */ + return 1; /* fail */ else - exit(0); + return 0; ]]) ],[ AC_MSG_RESULT([yes]) @@ -3872,11 +3881,11 @@ AC_DEFUN([CURL_CHECK_FUNC_STRERROR_R], [ buffer[0] = '\0'; error = strerror_r(EACCES, buffer, sizeof(buffer)); if(error) - exit(1); /* fail */ + return 1; /* fail */ if(buffer[0] == '\0') - exit(1); /* fail */ + return 1; /* fail */ else - exit(0); + return 0; ]]) ],[ AC_MSG_RESULT([yes]) diff --git a/packages/vms/report_openssl_version.c b/packages/vms/report_openssl_version.c index d08fe713b0..dd1713b244 100644 --- a/packages/vms/report_openssl_version.c +++ b/packages/vms/report_openssl_version.c @@ -48,7 +48,7 @@ int main(int argc, char **argv) if(argc < 1) { puts("report_openssl_version filename"); - exit(1); + return 1; } libptr = dlopen(argv[1], 0); @@ -65,7 +65,7 @@ int main(int argc, char **argv) if(!ssl_version) { puts("Unable to lookup version of OpenSSL"); - exit(1); + return 1; } version = ssl_version(SSLEAY_VERSION); @@ -91,9 +91,9 @@ int main(int argc, char **argv) status = LIB$SET_SYMBOL(&symbol_dsc, &value_dsc, &table_type); if(!$VMS_STATUS_SUCCESS(status)) { - exit(status); + return status; } } - exit(0); + return 0; } diff --git a/tests/http/clients/h2-pausing.c b/tests/http/clients/h2-pausing.c index 51d937ec31..9c6b88c37a 100644 --- a/tests/http/clients/h2-pausing.c +++ b/tests/http/clients/h2-pausing.c @@ -140,12 +140,6 @@ static int debug_cb(CURL *handle, curl_infotype type, return 0; } -#define ERR() \ - do { \ - fprintf(stderr, "something unexpected went wrong - bailing out!\n"); \ - exit(2); \ - } while(0) - static void usage(const char *msg) { if(msg) @@ -196,6 +190,13 @@ static size_t cb(char *data, size_t size, size_t nmemb, void *clientp) handle->idx, (long)realsize); return realsize; } + +#define ERR() \ + do { \ + fprintf(stderr, "something unexpected went wrong - bailing out!\n"); \ + return 2; \ + } while(0) + #endif /* !_MSC_VER */ int main(int argc, char *argv[]) @@ -254,19 +255,19 @@ int main(int argc, char *argv[]) cu = curl_url(); if(!cu) { fprintf(stderr, "out of memory\n"); - exit(1); + return 1; } if(curl_url_set(cu, CURLUPART_URL, url, 0)) { fprintf(stderr, "not a URL: '%s'\n", url); - exit(1); + return 1; } if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) { fprintf(stderr, "could not get host of '%s'\n", url); - exit(1); + return 1; } if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) { fprintf(stderr, "could not get port of '%s'\n", url); - exit(1); + return 1; } memset(&resolve, 0, sizeof(resolve)); curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", diff --git a/tests/http/clients/h2-upgrade-extreme.c b/tests/http/clients/h2-upgrade-extreme.c index 0cf939fc64..751d674152 100644 --- a/tests/http/clients/h2-upgrade-extreme.c +++ b/tests/http/clients/h2-upgrade-extreme.c @@ -138,24 +138,25 @@ static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *opaque) int main(int argc, char *argv[]) { const char *url; - CURLM *multi; + CURLM *multi = NULL; CURL *easy; CURLMcode mc; int running_handles = 0, start_count, numfds; CURLMsg *msg; int msgs_in_queue; char range[128]; + int exitcode = 1; if(argc != 2) { fprintf(stderr, "%s URL\n", argv[0]); - exit(2); + return 2; } url = argv[1]; multi = curl_multi_init(); if(!multi) { fprintf(stderr, "curl_multi_init failed\n"); - exit(1); + goto cleanup; } start_count = 200; @@ -164,7 +165,7 @@ int main(int argc, char *argv[]) easy = curl_easy_init(); if(!easy) { fprintf(stderr, "curl_easy_init failed\n"); - exit(1); + goto cleanup; } curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, debug_cb); @@ -186,8 +187,9 @@ int main(int argc, char *argv[]) mc = curl_multi_add_handle(multi, easy); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_add_handle: %s\n", - curl_multi_strerror(mc)); - exit(1); + curl_multi_strerror(mc)); + curl_easy_cleanup(easy); + goto cleanup; } --start_count; } @@ -195,16 +197,16 @@ int main(int argc, char *argv[]) mc = curl_multi_perform(multi, &running_handles); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_perform: %s\n", - curl_multi_strerror(mc)); - exit(1); + curl_multi_strerror(mc)); + goto cleanup; } if(running_handles) { mc = curl_multi_poll(multi, NULL, 0, 1000000, &numfds); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_poll: %s\n", - curl_multi_strerror(mc)); - exit(1); + curl_multi_strerror(mc)); + goto cleanup; } } @@ -224,12 +226,12 @@ int main(int argc, char *argv[]) else if(msg->data.result) { fprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T ": failed with %d\n", xfer_id, msg->data.result); - exit(1); + goto cleanup; } else if(status != 206) { fprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T ": wrong http status %ld (expected 206)\n", xfer_id, status); - exit(1); + goto cleanup; } curl_multi_remove_handle(multi, msg->easy_handle); curl_easy_cleanup(msg->easy_handle); @@ -244,5 +246,22 @@ int main(int argc, char *argv[]) } while(running_handles > 0 || start_count); fprintf(stderr, "exiting\n"); - exit(EXIT_SUCCESS); + exitcode = EXIT_SUCCESS; + +cleanup: + + if(multi) { + CURL **list = curl_multi_get_handles(multi); + if(list) { + int i; + for(i = 0; list[i]; i++) { + curl_multi_remove_handle(multi, list[i]); + curl_easy_cleanup(list[i]); + } + curl_free(list); + } + curl_multi_cleanup(multi); + } + + return exitcode; } diff --git a/tests/http/clients/tls-session-reuse.c b/tests/http/clients/tls-session-reuse.c index 9a63e779b3..ef9d84a131 100644 --- a/tests/http/clients/tls-session-reuse.c +++ b/tests/http/clients/tls-session-reuse.c @@ -136,9 +136,9 @@ static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *opaque) return size * nmemb; } -static void add_transfer(CURLM *multi, CURLSH *share, - struct curl_slist *resolve, - const char *url, int http_version) +static int add_transfer(CURLM *multi, CURLSH *share, + struct curl_slist *resolve, + const char *url, int http_version) { CURL *easy; CURLMcode mc; @@ -146,7 +146,7 @@ static void add_transfer(CURLM *multi, CURLSH *share, easy = curl_easy_init(); if(!easy) { fprintf(stderr, "curl_easy_init failed\n"); - exit(1); + return 1; } curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, debug_cb); @@ -167,30 +167,33 @@ static void add_transfer(CURLM *multi, CURLSH *share, mc = curl_multi_add_handle(multi, easy); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_add_handle: %s\n", - curl_multi_strerror(mc)); - exit(1); + curl_multi_strerror(mc)); + curl_easy_cleanup(easy); + return 1; } + return 0; } int main(int argc, char *argv[]) { const char *url; - CURLM *multi; + CURLM *multi = NULL; CURLMcode mc; int running_handles = 0, numfds; CURLMsg *msg; - CURLSH *share; + CURLSH *share = NULL; CURLU *cu; - struct curl_slist resolve; + struct curl_slist *resolve = NULL; char resolve_buf[1024]; int msgs_in_queue; int add_more, waits, ongoing = 0; - char *host, *port; + char *host = NULL, *port = NULL; int http_version = CURL_HTTP_VERSION_1_1; + int exitcode = 1; if(argc != 3) { fprintf(stderr, "%s proto URL\n", argv[0]); - exit(2); + return 2; } if(!strcmp("h2", argv[1])) @@ -202,41 +205,41 @@ int main(int argc, char *argv[]) cu = curl_url(); if(!cu) { fprintf(stderr, "out of memory\n"); - exit(1); + return 1; } if(curl_url_set(cu, CURLUPART_URL, url, 0)) { fprintf(stderr, "not a URL: '%s'\n", url); - exit(1); + goto cleanup; } if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) { fprintf(stderr, "could not get host of '%s'\n", url); - exit(1); + goto cleanup; } if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) { fprintf(stderr, "could not get port of '%s'\n", url); - exit(1); + goto cleanup; } - memset(&resolve, 0, sizeof(resolve)); curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", host, port); - curl_slist_append(&resolve, resolve_buf); + resolve = curl_slist_append(resolve, resolve_buf); multi = curl_multi_init(); if(!multi) { fprintf(stderr, "curl_multi_init failed\n"); - exit(1); + goto cleanup; } share = curl_share_init(); if(!share) { fprintf(stderr, "curl_share_init failed\n"); - exit(1); + goto cleanup; } curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); - add_transfer(multi, share, &resolve, url, http_version); + if(add_transfer(multi, share, resolve, url, http_version)) + goto cleanup; ++ongoing; add_more = 6; waits = 3; @@ -244,16 +247,16 @@ int main(int argc, char *argv[]) mc = curl_multi_perform(multi, &running_handles); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_perform: %s\n", - curl_multi_strerror(mc)); - exit(1); + curl_multi_strerror(mc)); + goto cleanup; } if(running_handles) { mc = curl_multi_poll(multi, NULL, 0, 1000000, &numfds); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_poll: %s\n", - curl_multi_strerror(mc)); - exit(1); + curl_multi_strerror(mc)); + goto cleanup; } } @@ -262,7 +265,8 @@ int main(int argc, char *argv[]) } else { while(add_more) { - add_transfer(multi, share, &resolve, url, http_version); + if(add_transfer(multi, share, resolve, url, http_version)) + goto cleanup; ++ongoing; --add_more; } @@ -284,12 +288,12 @@ int main(int argc, char *argv[]) else if(msg->data.result) { fprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T ": failed with %d\n", xfer_id, msg->data.result); - exit(1); + goto cleanup; } else if(status != 200) { fprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T ": wrong http status %ld (expected 200)\n", xfer_id, status); - exit(1); + goto cleanup; } curl_multi_remove_handle(multi, msg->easy_handle); curl_easy_cleanup(msg->easy_handle); @@ -305,5 +309,27 @@ int main(int argc, char *argv[]) } while(ongoing || add_more); fprintf(stderr, "exiting\n"); - exit(EXIT_SUCCESS); + exitcode = EXIT_SUCCESS; + +cleanup: + + if(multi) { + CURL **list = curl_multi_get_handles(multi); + if(list) { + int i; + for(i = 0; list[i]; i++) { + curl_multi_remove_handle(multi, list[i]); + curl_easy_cleanup(list[i]); + } + curl_free(list); + } + curl_multi_cleanup(multi); + } + curl_share_cleanup(share); + curl_slist_free_all(resolve); + curl_free(host); + curl_free(port); + curl_url_cleanup(cu); + + return exitcode; } diff --git a/tests/http/clients/upload-pausing.c b/tests/http/clients/upload-pausing.c index bd3d3eeea4..a9a439bf6b 100644 --- a/tests/http/clients/upload-pausing.c +++ b/tests/http/clients/upload-pausing.c @@ -180,12 +180,6 @@ static int progress_callback(void *clientp, return 0; } -#define ERR() \ - do { \ - fprintf(stderr, "something unexpected went wrong - bailing out!\n"); \ - exit(2); \ - } while(0) - static void usage(const char *msg) { if(msg) @@ -196,6 +190,13 @@ static void usage(const char *msg) " -V http_version (http/1.1, h2, h3) http version to use\n" ); } + +#define ERR() \ + do { \ + fprintf(stderr, "something unexpected went wrong - bailing out!\n"); \ + return 2; \ + } while(0) + #endif /* !_MSC_VER */ int main(int argc, char *argv[]) @@ -245,19 +246,19 @@ int main(int argc, char *argv[]) cu = curl_url(); if(!cu) { fprintf(stderr, "out of memory\n"); - exit(1); + return 1; } if(curl_url_set(cu, CURLUPART_URL, url, 0)) { fprintf(stderr, "not a URL: '%s'\n", url); - exit(1); + return 1; } if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) { fprintf(stderr, "could not get host of '%s'\n", url); - exit(1); + return 1; } if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) { fprintf(stderr, "could not get port of '%s'\n", url); - exit(1); + return 1; } memset(&resolve, 0, sizeof(resolve)); curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1", @@ -267,7 +268,7 @@ int main(int argc, char *argv[]) curl = curl_easy_init(); if(!curl) { fprintf(stderr, "out of memory\n"); - exit(1); + return 1; } /* We want to use our own read function. */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); diff --git a/tests/server/mqttd.c b/tests/server/mqttd.c index 7070a4f688..2fc3a5f94a 100644 --- a/tests/server/mqttd.c +++ b/tests/server/mqttd.c @@ -1018,8 +1018,8 @@ int main(int argc, char *argv[]) logdir, SERVERLOGS_LOCKDIR, ipv_inuse); #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif CURL_SET_BINMODE(stdin); diff --git a/tests/server/resolve.c b/tests/server/resolve.c index b09d50368f..56964e03a9 100644 --- a/tests/server/resolve.c +++ b/tests/server/resolve.c @@ -99,8 +99,8 @@ int main(int argc, char *argv[]) } #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif #if defined(CURLRES_IPV6) diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c index d3acefc0da..181568395f 100644 --- a/tests/server/rtspd.c +++ b/tests/server/rtspd.c @@ -1145,8 +1145,8 @@ int main(int argc, char *argv[]) logdir, SERVERLOGS_LOCKDIR, ipv_inuse); #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif install_signal_handlers(false); diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c index e164f5f2a5..18f75a5236 100644 --- a/tests/server/sockfilt.c +++ b/tests/server/sockfilt.c @@ -1507,8 +1507,8 @@ int main(int argc, char *argv[]) } #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif CURL_SET_BINMODE(stdin); diff --git a/tests/server/socksd.c b/tests/server/socksd.c index f63ffdb51b..92b261454e 100644 --- a/tests/server/socksd.c +++ b/tests/server/socksd.c @@ -1086,8 +1086,8 @@ int main(int argc, char *argv[]) } #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif CURL_SET_BINMODE(stdin); diff --git a/tests/server/sws.c b/tests/server/sws.c index c42bfe90b5..fa83bc6a9a 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -1611,7 +1611,7 @@ static void http_connect(curl_socket_t *infdp, if(!req2) { req2 = malloc(sizeof(*req2)); if(!req2) - exit(1); + goto http_connect_cleanup; /* fail */ } memset(req2, 0, sizeof(*req2)); logmsg("====> Client connect DATA"); @@ -2207,8 +2207,8 @@ int main(int argc, char *argv[]) is_proxy ? "-proxy" : "", socket_type); #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif install_signal_handlers(false); diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c index c296f7e20f..93f6537c6d 100644 --- a/tests/server/tftpd.c +++ b/tests/server/tftpd.c @@ -644,8 +644,8 @@ int main(int argc, char **argv) logdir, SERVERLOGS_LOCKDIR, ipv_inuse); #ifdef _WIN32 - win32_init(); - atexit(win32_cleanup); + if(win32_init()) + return 2; #endif install_signal_handlers(true); diff --git a/tests/server/util.c b/tests/server/util.c index 42a4f857e8..d9f6d2162a 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -153,7 +153,17 @@ void win32_perror(const char *msg) fprintf(stderr, "%s\n", buf); } -void win32_init(void) +static void win32_cleanup(void) +{ +#ifdef USE_WINSOCK + WSACleanup(); +#endif /* USE_WINSOCK */ + + /* flush buffers of all streams regardless of their mode */ + _flushall(); +} + +int win32_init(void) { #ifdef USE_WINSOCK WORD wVersionRequested; @@ -166,7 +176,7 @@ void win32_init(void) if(err) { perror("Winsock init failed"); logmsg("Error initialising Winsock -- aborting"); - exit(1); + return 1; } if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || @@ -174,19 +184,11 @@ void win32_init(void) WSACleanup(); perror("Winsock init failed"); logmsg("No suitable winsock.dll found -- aborting"); - exit(1); + return 1; } #endif /* USE_WINSOCK */ -} - -void win32_cleanup(void) -{ -#ifdef USE_WINSOCK - WSACleanup(); -#endif /* USE_WINSOCK */ - - /* flush buffers of all streams regardless of their mode */ - _flushall(); + atexit(win32_cleanup); + return 0; } /* socket-safe strerror (works on Winsock errors, too) */ diff --git a/tests/server/util.h b/tests/server/util.h index b225478ff9..991c0703ce 100644 --- a/tests/server/util.h +++ b/tests/server/util.h @@ -51,8 +51,7 @@ extern const char *cmdfile; #define perror(m) win32_perror(m) void win32_perror(const char *msg); -void win32_init(void); -void win32_cleanup(void); +int win32_init(void); const char *sstrerror(int err); #else /* _WIN32 */