1 | /*************************************************************************** |
2 | * _ _ ____ _ |
3 | * Project ___| | | | _ \| | |
4 | * / __| | | | |_) | | |
5 | * | (__| |_| | _ <| |___ |
6 | * \___|\___/|_| \_\_____| |
7 | * |
8 | * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. |
9 | * |
10 | * This software is licensed as described in the file COPYING, which |
11 | * you should have received as part of this distribution. The terms |
12 | * are also available at https://curl.se/docs/copyright.html. |
13 | * |
14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
15 | * copies of the Software, and permit persons to whom the Software is |
16 | * furnished to do so, under the terms of the COPYING file. |
17 | * |
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
19 | * KIND, either express or implied. |
20 | * |
21 | ***************************************************************************/ |
22 | #include "test.h" |
23 | |
24 | #ifdef HAVE_LOCALE_H |
25 | # include <locale.h> /* for setlocale() */ |
26 | #endif |
27 | |
28 | #ifdef HAVE_IO_H |
29 | # include <io.h> /* for setmode() */ |
30 | #endif |
31 | |
32 | #ifdef HAVE_FCNTL_H |
33 | # include <fcntl.h> /* for setmode() */ |
34 | #endif |
35 | |
36 | #ifdef USE_NSS |
37 | #include <nspr.h> |
38 | #endif |
39 | |
40 | #ifdef CURLDEBUG |
41 | # define MEMDEBUG_NODEFINES |
42 | # include "memdebug.h" |
43 | #endif |
44 | |
45 | int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, |
46 | struct timeval *tv) |
47 | { |
48 | if(nfds < 0) { |
49 | SET_SOCKERRNO(EINVAL); |
50 | return -1; |
51 | } |
52 | #ifdef USE_WINSOCK |
53 | /* |
54 | * Winsock select() requires that at least one of the three fd_set |
55 | * pointers is not NULL and points to a non-empty fdset. IOW Winsock |
56 | * select() can not be used to sleep without a single fd_set. |
57 | */ |
58 | if(!nfds) { |
59 | Sleep((1000*tv->tv_sec) + (DWORD)(((double)tv->tv_usec)/1000.0)); |
60 | return 0; |
61 | } |
62 | #endif |
63 | return select(nfds, rd, wr, exc, tv); |
64 | } |
65 | |
66 | void wait_ms(int ms) |
67 | { |
68 | struct timeval t; |
69 | t.tv_sec = ms/1000; |
70 | ms -= (int)t.tv_sec * 1000; |
71 | t.tv_usec = ms * 1000; |
72 | select_wrapper(0, NULL, NULL, NULL, &t); |
73 | } |
74 | |
75 | char *libtest_arg2 = NULL; |
76 | char *libtest_arg3 = NULL; |
77 | int test_argc; |
78 | char **test_argv; |
79 | |
80 | struct timeval tv_test_start; /* for test timing */ |
81 | |
82 | #ifdef UNITTESTS |
83 | int unitfail; /* for unittests */ |
84 | #endif |
85 | |
86 | #ifdef CURLDEBUG |
87 | static void memory_tracking_init(void) |
88 | { |
89 | char *env; |
90 | /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */ |
91 | env = curl_getenv("CURL_MEMDEBUG" ); |
92 | if(env) { |
93 | /* use the value as file name */ |
94 | char fname[CURL_MT_LOGFNAME_BUFSIZE]; |
95 | if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE) |
96 | env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0'; |
97 | strcpy(fname, env); |
98 | curl_free(env); |
99 | curl_dbg_memdebug(fname); |
100 | /* this weird stuff here is to make curl_free() get called before |
101 | curl_dbg_memdebug() as otherwise memory tracking will log a free() |
102 | without an alloc! */ |
103 | } |
104 | /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */ |
105 | env = curl_getenv("CURL_MEMLIMIT" ); |
106 | if(env) { |
107 | char *endptr; |
108 | long num = strtol(env, &endptr, 10); |
109 | if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) |
110 | curl_dbg_memlimit(num); |
111 | curl_free(env); |
112 | } |
113 | } |
114 | #else |
115 | # define memory_tracking_init() Curl_nop_stmt |
116 | #endif |
117 | |
118 | /* returns a hexdump in a static memory area */ |
119 | char *hexdump(const unsigned char *buffer, size_t len) |
120 | { |
121 | static char dump[200 * 3 + 1]; |
122 | char *p = dump; |
123 | size_t i; |
124 | if(len > 200) |
125 | return NULL; |
126 | for(i = 0; i<len; i++, p += 3) |
127 | msnprintf(p, 4, "%02x " , buffer[i]); |
128 | return dump; |
129 | } |
130 | |
131 | |
132 | int main(int argc, char **argv) |
133 | { |
134 | char *URL; |
135 | int result; |
136 | |
137 | #ifdef O_BINARY |
138 | # ifdef __HIGHC__ |
139 | _setmode(stdout, O_BINARY); |
140 | # else |
141 | setmode(fileno(stdout), O_BINARY); |
142 | # endif |
143 | #endif |
144 | |
145 | memory_tracking_init(); |
146 | |
147 | /* |
148 | * Setup proper locale from environment. This is needed to enable locale- |
149 | * specific behavior by the C library in order to test for undesired side |
150 | * effects that could cause in libcurl. |
151 | */ |
152 | #ifdef HAVE_SETLOCALE |
153 | setlocale(LC_ALL, "" ); |
154 | #endif |
155 | |
156 | if(argc< 2) { |
157 | fprintf(stderr, "Pass URL as argument please\n" ); |
158 | return 1; |
159 | } |
160 | |
161 | test_argc = argc; |
162 | test_argv = argv; |
163 | |
164 | if(argc>2) |
165 | libtest_arg2 = argv[2]; |
166 | |
167 | if(argc>3) |
168 | libtest_arg3 = argv[3]; |
169 | |
170 | URL = argv[1]; /* provide this to the rest */ |
171 | |
172 | fprintf(stderr, "URL: %s\n" , URL); |
173 | |
174 | result = test(URL); |
175 | |
176 | #ifdef USE_NSS |
177 | if(PR_Initialized()) |
178 | /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */ |
179 | PR_Cleanup(); |
180 | #endif |
181 | |
182 | return result; |
183 | } |
184 | |