113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci#include "test.h" 2513498266Sopenharmony_ci 2613498266Sopenharmony_ci#ifdef HAVE_LOCALE_H 2713498266Sopenharmony_ci# include <locale.h> /* for setlocale() */ 2813498266Sopenharmony_ci#endif 2913498266Sopenharmony_ci 3013498266Sopenharmony_ci#ifdef HAVE_IO_H 3113498266Sopenharmony_ci# include <io.h> /* for setmode() */ 3213498266Sopenharmony_ci#endif 3313498266Sopenharmony_ci 3413498266Sopenharmony_ci#ifdef HAVE_FCNTL_H 3513498266Sopenharmony_ci# include <fcntl.h> /* for setmode() */ 3613498266Sopenharmony_ci#endif 3713498266Sopenharmony_ci 3813498266Sopenharmony_ci#ifdef CURLDEBUG 3913498266Sopenharmony_ci# define MEMDEBUG_NODEFINES 4013498266Sopenharmony_ci# include "memdebug.h" 4113498266Sopenharmony_ci#endif 4213498266Sopenharmony_ci 4313498266Sopenharmony_ci#include "timediff.h" 4413498266Sopenharmony_ci 4513498266Sopenharmony_ciint select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, 4613498266Sopenharmony_ci struct timeval *tv) 4713498266Sopenharmony_ci{ 4813498266Sopenharmony_ci if(nfds < 0) { 4913498266Sopenharmony_ci SET_SOCKERRNO(EINVAL); 5013498266Sopenharmony_ci return -1; 5113498266Sopenharmony_ci } 5213498266Sopenharmony_ci#ifdef USE_WINSOCK 5313498266Sopenharmony_ci /* 5413498266Sopenharmony_ci * Winsock select() requires that at least one of the three fd_set 5513498266Sopenharmony_ci * pointers is not NULL and points to a non-empty fdset. IOW Winsock 5613498266Sopenharmony_ci * select() can not be used to sleep without a single fd_set. 5713498266Sopenharmony_ci */ 5813498266Sopenharmony_ci if(!nfds) { 5913498266Sopenharmony_ci Sleep((DWORD)curlx_tvtoms(tv)); 6013498266Sopenharmony_ci return 0; 6113498266Sopenharmony_ci } 6213498266Sopenharmony_ci#endif 6313498266Sopenharmony_ci return select(nfds, rd, wr, exc, tv); 6413498266Sopenharmony_ci} 6513498266Sopenharmony_ci 6613498266Sopenharmony_civoid wait_ms(int ms) 6713498266Sopenharmony_ci{ 6813498266Sopenharmony_ci if(ms < 0) 6913498266Sopenharmony_ci return; 7013498266Sopenharmony_ci#ifdef USE_WINSOCK 7113498266Sopenharmony_ci Sleep((DWORD)ms); 7213498266Sopenharmony_ci#else 7313498266Sopenharmony_ci { 7413498266Sopenharmony_ci struct timeval t; 7513498266Sopenharmony_ci curlx_mstotv(&t, ms); 7613498266Sopenharmony_ci select_wrapper(0, NULL, NULL, NULL, &t); 7713498266Sopenharmony_ci } 7813498266Sopenharmony_ci#endif 7913498266Sopenharmony_ci} 8013498266Sopenharmony_ci 8113498266Sopenharmony_cichar *libtest_arg2 = NULL; 8213498266Sopenharmony_cichar *libtest_arg3 = NULL; 8313498266Sopenharmony_ciint test_argc; 8413498266Sopenharmony_cichar **test_argv; 8513498266Sopenharmony_ci 8613498266Sopenharmony_cistruct timeval tv_test_start; /* for test timing */ 8713498266Sopenharmony_ci 8813498266Sopenharmony_ciint unitfail; /* for unittests */ 8913498266Sopenharmony_ci 9013498266Sopenharmony_ci#ifdef CURLDEBUG 9113498266Sopenharmony_cistatic void memory_tracking_init(void) 9213498266Sopenharmony_ci{ 9313498266Sopenharmony_ci char *env; 9413498266Sopenharmony_ci /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */ 9513498266Sopenharmony_ci env = curl_getenv("CURL_MEMDEBUG"); 9613498266Sopenharmony_ci if(env) { 9713498266Sopenharmony_ci /* use the value as file name */ 9813498266Sopenharmony_ci char fname[CURL_MT_LOGFNAME_BUFSIZE]; 9913498266Sopenharmony_ci if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE) 10013498266Sopenharmony_ci env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0'; 10113498266Sopenharmony_ci strcpy(fname, env); 10213498266Sopenharmony_ci curl_free(env); 10313498266Sopenharmony_ci curl_dbg_memdebug(fname); 10413498266Sopenharmony_ci /* this weird stuff here is to make curl_free() get called before 10513498266Sopenharmony_ci curl_dbg_memdebug() as otherwise memory tracking will log a free() 10613498266Sopenharmony_ci without an alloc! */ 10713498266Sopenharmony_ci } 10813498266Sopenharmony_ci /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */ 10913498266Sopenharmony_ci env = curl_getenv("CURL_MEMLIMIT"); 11013498266Sopenharmony_ci if(env) { 11113498266Sopenharmony_ci char *endptr; 11213498266Sopenharmony_ci long num = strtol(env, &endptr, 10); 11313498266Sopenharmony_ci if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) 11413498266Sopenharmony_ci curl_dbg_memlimit(num); 11513498266Sopenharmony_ci curl_free(env); 11613498266Sopenharmony_ci } 11713498266Sopenharmony_ci} 11813498266Sopenharmony_ci#else 11913498266Sopenharmony_ci# define memory_tracking_init() Curl_nop_stmt 12013498266Sopenharmony_ci#endif 12113498266Sopenharmony_ci 12213498266Sopenharmony_ci/* returns a hexdump in a static memory area */ 12313498266Sopenharmony_cichar *hexdump(const unsigned char *buffer, size_t len) 12413498266Sopenharmony_ci{ 12513498266Sopenharmony_ci static char dump[200 * 3 + 1]; 12613498266Sopenharmony_ci char *p = dump; 12713498266Sopenharmony_ci size_t i; 12813498266Sopenharmony_ci if(len > 200) 12913498266Sopenharmony_ci return NULL; 13013498266Sopenharmony_ci for(i = 0; i<len; i++, p += 3) 13113498266Sopenharmony_ci msnprintf(p, 4, "%02x ", buffer[i]); 13213498266Sopenharmony_ci return dump; 13313498266Sopenharmony_ci} 13413498266Sopenharmony_ci 13513498266Sopenharmony_ci 13613498266Sopenharmony_ciint main(int argc, char **argv) 13713498266Sopenharmony_ci{ 13813498266Sopenharmony_ci char *URL; 13913498266Sopenharmony_ci int result; 14013498266Sopenharmony_ci 14113498266Sopenharmony_ci#ifdef O_BINARY 14213498266Sopenharmony_ci# ifdef __HIGHC__ 14313498266Sopenharmony_ci _setmode(stdout, O_BINARY); 14413498266Sopenharmony_ci# else 14513498266Sopenharmony_ci setmode(fileno(stdout), O_BINARY); 14613498266Sopenharmony_ci# endif 14713498266Sopenharmony_ci#endif 14813498266Sopenharmony_ci 14913498266Sopenharmony_ci memory_tracking_init(); 15013498266Sopenharmony_ci 15113498266Sopenharmony_ci /* 15213498266Sopenharmony_ci * Setup proper locale from environment. This is needed to enable locale- 15313498266Sopenharmony_ci * specific behavior by the C library in order to test for undesired side 15413498266Sopenharmony_ci * effects that could cause in libcurl. 15513498266Sopenharmony_ci */ 15613498266Sopenharmony_ci#ifdef HAVE_SETLOCALE 15713498266Sopenharmony_ci setlocale(LC_ALL, ""); 15813498266Sopenharmony_ci#endif 15913498266Sopenharmony_ci 16013498266Sopenharmony_ci if(argc< 2) { 16113498266Sopenharmony_ci fprintf(stderr, "Pass URL as argument please\n"); 16213498266Sopenharmony_ci return 1; 16313498266Sopenharmony_ci } 16413498266Sopenharmony_ci 16513498266Sopenharmony_ci test_argc = argc; 16613498266Sopenharmony_ci test_argv = argv; 16713498266Sopenharmony_ci 16813498266Sopenharmony_ci if(argc>2) 16913498266Sopenharmony_ci libtest_arg2 = argv[2]; 17013498266Sopenharmony_ci 17113498266Sopenharmony_ci if(argc>3) 17213498266Sopenharmony_ci libtest_arg3 = argv[3]; 17313498266Sopenharmony_ci 17413498266Sopenharmony_ci URL = argv[1]; /* provide this to the rest */ 17513498266Sopenharmony_ci 17613498266Sopenharmony_ci fprintf(stderr, "URL: %s\n", URL); 17713498266Sopenharmony_ci 17813498266Sopenharmony_ci result = test(URL); 17913498266Sopenharmony_ci fprintf(stderr, "Test ended with result %d\n", result); 18013498266Sopenharmony_ci 18113498266Sopenharmony_ci#ifdef _WIN32 18213498266Sopenharmony_ci /* flush buffers of all streams regardless of mode */ 18313498266Sopenharmony_ci _flushall(); 18413498266Sopenharmony_ci#endif 18513498266Sopenharmony_ci 18613498266Sopenharmony_ci /* Regular program status codes are limited to 0..127 and 126 and 127 have 18713498266Sopenharmony_ci * special meanings by the shell, so limit a normal return code to 125 */ 18813498266Sopenharmony_ci return result <= 125 ? result : 125; 18913498266Sopenharmony_ci} 190