1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "test.h"
25*6236dae4SAndroid Build Coastguard Worker
26*6236dae4SAndroid Build Coastguard Worker #include <fcntl.h>
27*6236dae4SAndroid Build Coastguard Worker
28*6236dae4SAndroid Build Coastguard Worker #include "testutil.h"
29*6236dae4SAndroid Build Coastguard Worker #include "warnless.h"
30*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
31*6236dae4SAndroid Build Coastguard Worker
32*6236dae4SAndroid Build Coastguard Worker #define TEST_HANG_TIMEOUT 60 * 1000
33*6236dae4SAndroid Build Coastguard Worker
34*6236dae4SAndroid Build Coastguard Worker struct Sockets {
35*6236dae4SAndroid Build Coastguard Worker curl_socket_t *sockets;
36*6236dae4SAndroid Build Coastguard Worker int count; /* number of sockets actually stored in array */
37*6236dae4SAndroid Build Coastguard Worker int max_count; /* max number of sockets that fit in allocated array */
38*6236dae4SAndroid Build Coastguard Worker };
39*6236dae4SAndroid Build Coastguard Worker
40*6236dae4SAndroid Build Coastguard Worker struct ReadWriteSockets {
41*6236dae4SAndroid Build Coastguard Worker struct Sockets read, write;
42*6236dae4SAndroid Build Coastguard Worker };
43*6236dae4SAndroid Build Coastguard Worker
44*6236dae4SAndroid Build Coastguard Worker /**
45*6236dae4SAndroid Build Coastguard Worker * Remove a file descriptor from a sockets array.
46*6236dae4SAndroid Build Coastguard Worker */
removeFd(struct Sockets * sockets,curl_socket_t fd,int mention)47*6236dae4SAndroid Build Coastguard Worker static void removeFd(struct Sockets *sockets, curl_socket_t fd, int mention)
48*6236dae4SAndroid Build Coastguard Worker {
49*6236dae4SAndroid Build Coastguard Worker int i;
50*6236dae4SAndroid Build Coastguard Worker
51*6236dae4SAndroid Build Coastguard Worker if(mention)
52*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Remove socket fd %d\n", (int) fd);
53*6236dae4SAndroid Build Coastguard Worker
54*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < sockets->count; ++i) {
55*6236dae4SAndroid Build Coastguard Worker if(sockets->sockets[i] == fd) {
56*6236dae4SAndroid Build Coastguard Worker if(i < sockets->count - 1)
57*6236dae4SAndroid Build Coastguard Worker memmove(&sockets->sockets[i], &sockets->sockets[i + 1],
58*6236dae4SAndroid Build Coastguard Worker sizeof(curl_socket_t) * (sockets->count - (i + 1)));
59*6236dae4SAndroid Build Coastguard Worker --sockets->count;
60*6236dae4SAndroid Build Coastguard Worker }
61*6236dae4SAndroid Build Coastguard Worker }
62*6236dae4SAndroid Build Coastguard Worker }
63*6236dae4SAndroid Build Coastguard Worker
64*6236dae4SAndroid Build Coastguard Worker /**
65*6236dae4SAndroid Build Coastguard Worker * Add a file descriptor to a sockets array.
66*6236dae4SAndroid Build Coastguard Worker */
addFd(struct Sockets * sockets,curl_socket_t fd,const char * what)67*6236dae4SAndroid Build Coastguard Worker static void addFd(struct Sockets *sockets, curl_socket_t fd, const char *what)
68*6236dae4SAndroid Build Coastguard Worker {
69*6236dae4SAndroid Build Coastguard Worker /**
70*6236dae4SAndroid Build Coastguard Worker * To ensure we only have each file descriptor once, we remove it then add
71*6236dae4SAndroid Build Coastguard Worker * it again.
72*6236dae4SAndroid Build Coastguard Worker */
73*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Add socket fd %d for %s\n", (int) fd, what);
74*6236dae4SAndroid Build Coastguard Worker removeFd(sockets, fd, 0);
75*6236dae4SAndroid Build Coastguard Worker /*
76*6236dae4SAndroid Build Coastguard Worker * Allocate array storage when required.
77*6236dae4SAndroid Build Coastguard Worker */
78*6236dae4SAndroid Build Coastguard Worker if(!sockets->sockets) {
79*6236dae4SAndroid Build Coastguard Worker sockets->sockets = malloc(sizeof(curl_socket_t) * 20U);
80*6236dae4SAndroid Build Coastguard Worker if(!sockets->sockets)
81*6236dae4SAndroid Build Coastguard Worker return;
82*6236dae4SAndroid Build Coastguard Worker sockets->max_count = 20;
83*6236dae4SAndroid Build Coastguard Worker }
84*6236dae4SAndroid Build Coastguard Worker else if(sockets->count >= sockets->max_count) {
85*6236dae4SAndroid Build Coastguard Worker /* this can't happen in normal cases */
86*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "too many file handles error\n");
87*6236dae4SAndroid Build Coastguard Worker exit(2);
88*6236dae4SAndroid Build Coastguard Worker }
89*6236dae4SAndroid Build Coastguard Worker /*
90*6236dae4SAndroid Build Coastguard Worker * Add file descriptor to array.
91*6236dae4SAndroid Build Coastguard Worker */
92*6236dae4SAndroid Build Coastguard Worker sockets->sockets[sockets->count] = fd;
93*6236dae4SAndroid Build Coastguard Worker ++sockets->count;
94*6236dae4SAndroid Build Coastguard Worker }
95*6236dae4SAndroid Build Coastguard Worker
96*6236dae4SAndroid Build Coastguard Worker /**
97*6236dae4SAndroid Build Coastguard Worker * Callback invoked by curl to poll reading / writing of a socket.
98*6236dae4SAndroid Build Coastguard Worker */
curlSocketCallback(CURL * easy,curl_socket_t s,int action,void * userp,void * socketp)99*6236dae4SAndroid Build Coastguard Worker static int curlSocketCallback(CURL *easy, curl_socket_t s, int action,
100*6236dae4SAndroid Build Coastguard Worker void *userp, void *socketp)
101*6236dae4SAndroid Build Coastguard Worker {
102*6236dae4SAndroid Build Coastguard Worker struct ReadWriteSockets *sockets = userp;
103*6236dae4SAndroid Build Coastguard Worker
104*6236dae4SAndroid Build Coastguard Worker (void)easy; /* unused */
105*6236dae4SAndroid Build Coastguard Worker (void)socketp; /* unused */
106*6236dae4SAndroid Build Coastguard Worker
107*6236dae4SAndroid Build Coastguard Worker if(action == CURL_POLL_IN || action == CURL_POLL_INOUT)
108*6236dae4SAndroid Build Coastguard Worker addFd(&sockets->read, s, "read");
109*6236dae4SAndroid Build Coastguard Worker
110*6236dae4SAndroid Build Coastguard Worker if(action == CURL_POLL_OUT || action == CURL_POLL_INOUT)
111*6236dae4SAndroid Build Coastguard Worker addFd(&sockets->write, s, "write");
112*6236dae4SAndroid Build Coastguard Worker
113*6236dae4SAndroid Build Coastguard Worker if(action == CURL_POLL_REMOVE) {
114*6236dae4SAndroid Build Coastguard Worker removeFd(&sockets->read, s, 1);
115*6236dae4SAndroid Build Coastguard Worker removeFd(&sockets->write, s, 0);
116*6236dae4SAndroid Build Coastguard Worker }
117*6236dae4SAndroid Build Coastguard Worker
118*6236dae4SAndroid Build Coastguard Worker return 0;
119*6236dae4SAndroid Build Coastguard Worker }
120*6236dae4SAndroid Build Coastguard Worker
121*6236dae4SAndroid Build Coastguard Worker /**
122*6236dae4SAndroid Build Coastguard Worker * Callback invoked by curl to set a timeout.
123*6236dae4SAndroid Build Coastguard Worker */
curlTimerCallback(CURLM * multi,long timeout_ms,void * userp)124*6236dae4SAndroid Build Coastguard Worker static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp)
125*6236dae4SAndroid Build Coastguard Worker {
126*6236dae4SAndroid Build Coastguard Worker struct timeval *timeout = userp;
127*6236dae4SAndroid Build Coastguard Worker
128*6236dae4SAndroid Build Coastguard Worker (void)multi; /* unused */
129*6236dae4SAndroid Build Coastguard Worker if(timeout_ms != -1) {
130*6236dae4SAndroid Build Coastguard Worker *timeout = tutil_tvnow();
131*6236dae4SAndroid Build Coastguard Worker timeout->tv_usec += (int)timeout_ms * 1000;
132*6236dae4SAndroid Build Coastguard Worker }
133*6236dae4SAndroid Build Coastguard Worker else {
134*6236dae4SAndroid Build Coastguard Worker timeout->tv_sec = -1;
135*6236dae4SAndroid Build Coastguard Worker }
136*6236dae4SAndroid Build Coastguard Worker return 0;
137*6236dae4SAndroid Build Coastguard Worker }
138*6236dae4SAndroid Build Coastguard Worker
139*6236dae4SAndroid Build Coastguard Worker /**
140*6236dae4SAndroid Build Coastguard Worker * Check for curl completion.
141*6236dae4SAndroid Build Coastguard Worker */
checkForCompletion(CURLM * curl,int * success)142*6236dae4SAndroid Build Coastguard Worker static int checkForCompletion(CURLM *curl, int *success)
143*6236dae4SAndroid Build Coastguard Worker {
144*6236dae4SAndroid Build Coastguard Worker int result = 0;
145*6236dae4SAndroid Build Coastguard Worker *success = 0;
146*6236dae4SAndroid Build Coastguard Worker while(1) {
147*6236dae4SAndroid Build Coastguard Worker int numMessages;
148*6236dae4SAndroid Build Coastguard Worker CURLMsg *message = curl_multi_info_read(curl, &numMessages);
149*6236dae4SAndroid Build Coastguard Worker if(!message)
150*6236dae4SAndroid Build Coastguard Worker break;
151*6236dae4SAndroid Build Coastguard Worker if(message->msg == CURLMSG_DONE) {
152*6236dae4SAndroid Build Coastguard Worker result = 1;
153*6236dae4SAndroid Build Coastguard Worker if(message->data.result == CURLE_OK)
154*6236dae4SAndroid Build Coastguard Worker *success = 1;
155*6236dae4SAndroid Build Coastguard Worker else
156*6236dae4SAndroid Build Coastguard Worker *success = 0;
157*6236dae4SAndroid Build Coastguard Worker }
158*6236dae4SAndroid Build Coastguard Worker else {
159*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Got an unexpected message from curl: %i\n",
160*6236dae4SAndroid Build Coastguard Worker (int)message->msg);
161*6236dae4SAndroid Build Coastguard Worker result = 1;
162*6236dae4SAndroid Build Coastguard Worker *success = 0;
163*6236dae4SAndroid Build Coastguard Worker }
164*6236dae4SAndroid Build Coastguard Worker }
165*6236dae4SAndroid Build Coastguard Worker return result;
166*6236dae4SAndroid Build Coastguard Worker }
167*6236dae4SAndroid Build Coastguard Worker
getMicroSecondTimeout(struct timeval * timeout)168*6236dae4SAndroid Build Coastguard Worker static int getMicroSecondTimeout(struct timeval *timeout)
169*6236dae4SAndroid Build Coastguard Worker {
170*6236dae4SAndroid Build Coastguard Worker struct timeval now;
171*6236dae4SAndroid Build Coastguard Worker ssize_t result;
172*6236dae4SAndroid Build Coastguard Worker now = tutil_tvnow();
173*6236dae4SAndroid Build Coastguard Worker result = (ssize_t)((timeout->tv_sec - now.tv_sec) * 1000000 +
174*6236dae4SAndroid Build Coastguard Worker timeout->tv_usec - now.tv_usec);
175*6236dae4SAndroid Build Coastguard Worker if(result < 0)
176*6236dae4SAndroid Build Coastguard Worker result = 0;
177*6236dae4SAndroid Build Coastguard Worker
178*6236dae4SAndroid Build Coastguard Worker return curlx_sztosi(result);
179*6236dae4SAndroid Build Coastguard Worker }
180*6236dae4SAndroid Build Coastguard Worker
181*6236dae4SAndroid Build Coastguard Worker /**
182*6236dae4SAndroid Build Coastguard Worker * Update a fd_set with all of the sockets in use.
183*6236dae4SAndroid Build Coastguard Worker */
updateFdSet(struct Sockets * sockets,fd_set * fdset,curl_socket_t * maxFd)184*6236dae4SAndroid Build Coastguard Worker static void updateFdSet(struct Sockets *sockets, fd_set* fdset,
185*6236dae4SAndroid Build Coastguard Worker curl_socket_t *maxFd)
186*6236dae4SAndroid Build Coastguard Worker {
187*6236dae4SAndroid Build Coastguard Worker int i;
188*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < sockets->count; ++i) {
189*6236dae4SAndroid Build Coastguard Worker FD_SET(sockets->sockets[i], fdset);
190*6236dae4SAndroid Build Coastguard Worker if(*maxFd < sockets->sockets[i] + 1) {
191*6236dae4SAndroid Build Coastguard Worker *maxFd = sockets->sockets[i] + 1;
192*6236dae4SAndroid Build Coastguard Worker }
193*6236dae4SAndroid Build Coastguard Worker }
194*6236dae4SAndroid Build Coastguard Worker }
195*6236dae4SAndroid Build Coastguard Worker
notifyCurl(CURLM * curl,curl_socket_t s,int evBitmask,const char * info)196*6236dae4SAndroid Build Coastguard Worker static void notifyCurl(CURLM *curl, curl_socket_t s, int evBitmask,
197*6236dae4SAndroid Build Coastguard Worker const char *info)
198*6236dae4SAndroid Build Coastguard Worker {
199*6236dae4SAndroid Build Coastguard Worker int numhandles = 0;
200*6236dae4SAndroid Build Coastguard Worker CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles);
201*6236dae4SAndroid Build Coastguard Worker if(result != CURLM_OK) {
202*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Curl error on %s: %i (%s)\n",
203*6236dae4SAndroid Build Coastguard Worker info, result, curl_multi_strerror(result));
204*6236dae4SAndroid Build Coastguard Worker }
205*6236dae4SAndroid Build Coastguard Worker }
206*6236dae4SAndroid Build Coastguard Worker
207*6236dae4SAndroid Build Coastguard Worker /**
208*6236dae4SAndroid Build Coastguard Worker * Invoke curl when a file descriptor is set.
209*6236dae4SAndroid Build Coastguard Worker */
checkFdSet(CURLM * curl,struct Sockets * sockets,fd_set * fdset,int evBitmask,const char * name)210*6236dae4SAndroid Build Coastguard Worker static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset,
211*6236dae4SAndroid Build Coastguard Worker int evBitmask, const char *name)
212*6236dae4SAndroid Build Coastguard Worker {
213*6236dae4SAndroid Build Coastguard Worker int i;
214*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < sockets->count; ++i) {
215*6236dae4SAndroid Build Coastguard Worker if(FD_ISSET(sockets->sockets[i], fdset)) {
216*6236dae4SAndroid Build Coastguard Worker notifyCurl(curl, sockets->sockets[i], evBitmask, name);
217*6236dae4SAndroid Build Coastguard Worker }
218*6236dae4SAndroid Build Coastguard Worker }
219*6236dae4SAndroid Build Coastguard Worker }
220*6236dae4SAndroid Build Coastguard Worker
test(char * URL)221*6236dae4SAndroid Build Coastguard Worker CURLcode test(char *URL)
222*6236dae4SAndroid Build Coastguard Worker {
223*6236dae4SAndroid Build Coastguard Worker CURLcode res = CURLE_OK;
224*6236dae4SAndroid Build Coastguard Worker CURL *curl = NULL;
225*6236dae4SAndroid Build Coastguard Worker FILE *hd_src = NULL;
226*6236dae4SAndroid Build Coastguard Worker int hd;
227*6236dae4SAndroid Build Coastguard Worker struct_stat file_info;
228*6236dae4SAndroid Build Coastguard Worker CURLM *m = NULL;
229*6236dae4SAndroid Build Coastguard Worker struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}};
230*6236dae4SAndroid Build Coastguard Worker struct timeval timeout = {-1, 0};
231*6236dae4SAndroid Build Coastguard Worker int success = 0;
232*6236dae4SAndroid Build Coastguard Worker
233*6236dae4SAndroid Build Coastguard Worker assert(test_argc >= 5);
234*6236dae4SAndroid Build Coastguard Worker
235*6236dae4SAndroid Build Coastguard Worker start_test_timing();
236*6236dae4SAndroid Build Coastguard Worker
237*6236dae4SAndroid Build Coastguard Worker if(!libtest_arg3) {
238*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Usage: lib582 [url] [filename] [username]\n");
239*6236dae4SAndroid Build Coastguard Worker return TEST_ERR_USAGE;
240*6236dae4SAndroid Build Coastguard Worker }
241*6236dae4SAndroid Build Coastguard Worker
242*6236dae4SAndroid Build Coastguard Worker hd_src = fopen(libtest_arg2, "rb");
243*6236dae4SAndroid Build Coastguard Worker if(!hd_src) {
244*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "fopen() failed with error: %d (%s)\n",
245*6236dae4SAndroid Build Coastguard Worker errno, strerror(errno));
246*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
247*6236dae4SAndroid Build Coastguard Worker return TEST_ERR_FOPEN;
248*6236dae4SAndroid Build Coastguard Worker }
249*6236dae4SAndroid Build Coastguard Worker
250*6236dae4SAndroid Build Coastguard Worker /* get the file size of the local file */
251*6236dae4SAndroid Build Coastguard Worker hd = fstat(fileno(hd_src), &file_info);
252*6236dae4SAndroid Build Coastguard Worker if(hd == -1) {
253*6236dae4SAndroid Build Coastguard Worker /* can't open file, bail out */
254*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "fstat() failed with error: %d (%s)\n",
255*6236dae4SAndroid Build Coastguard Worker errno, strerror(errno));
256*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2);
257*6236dae4SAndroid Build Coastguard Worker fclose(hd_src);
258*6236dae4SAndroid Build Coastguard Worker return TEST_ERR_FSTAT;
259*6236dae4SAndroid Build Coastguard Worker }
260*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size);
261*6236dae4SAndroid Build Coastguard Worker
262*6236dae4SAndroid Build Coastguard Worker res_global_init(CURL_GLOBAL_ALL);
263*6236dae4SAndroid Build Coastguard Worker if(res) {
264*6236dae4SAndroid Build Coastguard Worker fclose(hd_src);
265*6236dae4SAndroid Build Coastguard Worker return res;
266*6236dae4SAndroid Build Coastguard Worker }
267*6236dae4SAndroid Build Coastguard Worker
268*6236dae4SAndroid Build Coastguard Worker easy_init(curl);
269*6236dae4SAndroid Build Coastguard Worker
270*6236dae4SAndroid Build Coastguard Worker /* enable uploading */
271*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_UPLOAD, 1L);
272*6236dae4SAndroid Build Coastguard Worker
273*6236dae4SAndroid Build Coastguard Worker /* specify target */
274*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_URL, URL);
275*6236dae4SAndroid Build Coastguard Worker
276*6236dae4SAndroid Build Coastguard Worker /* go verbose */
277*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_VERBOSE, 1L);
278*6236dae4SAndroid Build Coastguard Worker
279*6236dae4SAndroid Build Coastguard Worker /* now specify which file to upload */
280*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_READDATA, hd_src);
281*6236dae4SAndroid Build Coastguard Worker
282*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_USERPWD, libtest_arg3);
283*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, test_argv[4]);
284*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, test_argv[5]);
285*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
286*6236dae4SAndroid Build Coastguard Worker
287*6236dae4SAndroid Build Coastguard Worker easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
288*6236dae4SAndroid Build Coastguard Worker
289*6236dae4SAndroid Build Coastguard Worker multi_init(m);
290*6236dae4SAndroid Build Coastguard Worker
291*6236dae4SAndroid Build Coastguard Worker multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback);
292*6236dae4SAndroid Build Coastguard Worker multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets);
293*6236dae4SAndroid Build Coastguard Worker
294*6236dae4SAndroid Build Coastguard Worker multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback);
295*6236dae4SAndroid Build Coastguard Worker multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
296*6236dae4SAndroid Build Coastguard Worker
297*6236dae4SAndroid Build Coastguard Worker multi_add_handle(m, curl);
298*6236dae4SAndroid Build Coastguard Worker
299*6236dae4SAndroid Build Coastguard Worker while(!checkForCompletion(m, &success)) {
300*6236dae4SAndroid Build Coastguard Worker fd_set readSet, writeSet;
301*6236dae4SAndroid Build Coastguard Worker curl_socket_t maxFd = 0;
302*6236dae4SAndroid Build Coastguard Worker struct timeval tv = {10, 0};
303*6236dae4SAndroid Build Coastguard Worker
304*6236dae4SAndroid Build Coastguard Worker FD_ZERO(&readSet);
305*6236dae4SAndroid Build Coastguard Worker FD_ZERO(&writeSet);
306*6236dae4SAndroid Build Coastguard Worker updateFdSet(&sockets.read, &readSet, &maxFd);
307*6236dae4SAndroid Build Coastguard Worker updateFdSet(&sockets.write, &writeSet, &maxFd);
308*6236dae4SAndroid Build Coastguard Worker
309*6236dae4SAndroid Build Coastguard Worker if(timeout.tv_sec != -1) {
310*6236dae4SAndroid Build Coastguard Worker int usTimeout = getMicroSecondTimeout(&timeout);
311*6236dae4SAndroid Build Coastguard Worker tv.tv_sec = usTimeout / 1000000;
312*6236dae4SAndroid Build Coastguard Worker tv.tv_usec = usTimeout % 1000000;
313*6236dae4SAndroid Build Coastguard Worker }
314*6236dae4SAndroid Build Coastguard Worker else if(maxFd <= 0) {
315*6236dae4SAndroid Build Coastguard Worker tv.tv_sec = 0;
316*6236dae4SAndroid Build Coastguard Worker tv.tv_usec = 100000;
317*6236dae4SAndroid Build Coastguard Worker }
318*6236dae4SAndroid Build Coastguard Worker
319*6236dae4SAndroid Build Coastguard Worker select_test((int)maxFd, &readSet, &writeSet, NULL, &tv);
320*6236dae4SAndroid Build Coastguard Worker
321*6236dae4SAndroid Build Coastguard Worker /* Check the sockets for reading / writing */
322*6236dae4SAndroid Build Coastguard Worker checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, "read");
323*6236dae4SAndroid Build Coastguard Worker checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, "write");
324*6236dae4SAndroid Build Coastguard Worker
325*6236dae4SAndroid Build Coastguard Worker if(timeout.tv_sec != -1 && getMicroSecondTimeout(&timeout) == 0) {
326*6236dae4SAndroid Build Coastguard Worker /* Curl's timer has elapsed. */
327*6236dae4SAndroid Build Coastguard Worker notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout");
328*6236dae4SAndroid Build Coastguard Worker }
329*6236dae4SAndroid Build Coastguard Worker
330*6236dae4SAndroid Build Coastguard Worker abort_on_test_timeout();
331*6236dae4SAndroid Build Coastguard Worker }
332*6236dae4SAndroid Build Coastguard Worker
333*6236dae4SAndroid Build Coastguard Worker if(!success) {
334*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "Error uploading file.\n");
335*6236dae4SAndroid Build Coastguard Worker res = TEST_ERR_MAJOR_BAD;
336*6236dae4SAndroid Build Coastguard Worker }
337*6236dae4SAndroid Build Coastguard Worker
338*6236dae4SAndroid Build Coastguard Worker test_cleanup:
339*6236dae4SAndroid Build Coastguard Worker
340*6236dae4SAndroid Build Coastguard Worker /* proper cleanup sequence - type PB */
341*6236dae4SAndroid Build Coastguard Worker
342*6236dae4SAndroid Build Coastguard Worker curl_multi_remove_handle(m, curl);
343*6236dae4SAndroid Build Coastguard Worker curl_easy_cleanup(curl);
344*6236dae4SAndroid Build Coastguard Worker curl_multi_cleanup(m);
345*6236dae4SAndroid Build Coastguard Worker curl_global_cleanup();
346*6236dae4SAndroid Build Coastguard Worker
347*6236dae4SAndroid Build Coastguard Worker /* close the local file */
348*6236dae4SAndroid Build Coastguard Worker fclose(hd_src);
349*6236dae4SAndroid Build Coastguard Worker
350*6236dae4SAndroid Build Coastguard Worker /* free local memory */
351*6236dae4SAndroid Build Coastguard Worker free(sockets.read.sockets);
352*6236dae4SAndroid Build Coastguard Worker free(sockets.write.sockets);
353*6236dae4SAndroid Build Coastguard Worker
354*6236dae4SAndroid Build Coastguard Worker return res;
355*6236dae4SAndroid Build Coastguard Worker }
356