/***************************************************************************1* _ _ ____ _2* Project ___| | | | _ \| |3* / __| | | | |_) | |4* | (__| |_| | _ <| |___5* \___|\___/|_| \_\_____|6*7* Copyright (C) Daniel Stenberg, <[email protected]>, et al.8*9* This software is licensed as described in the file COPYING, which10* you should have received as part of this distribution. The terms11* are also available at https://curl.se/docs/copyright.html.12*13* You may opt to use, copy, modify, merge, publish, distribute and/or sell14* copies of the Software, and permit persons to whom the Software is15* furnished to do so, under the terms of the COPYING file.16*17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY18* KIND, either express or implied.19*20* SPDX-License-Identifier: curl21*22***************************************************************************/23#include "first.h"2425#include "memdebug.h"2627static CURLcode test_lib1531(const char *URL)28{29static char const testData[] = ".abc\0xyz";30static curl_off_t const testDataSize = sizeof(testData) - 1;3132CURL *curl;33CURLM *multi;34int still_running; /* keep number of running handles */35CURLMsg *msg; /* for picking up messages with the transfer status */36int msgs_left; /* how many messages are left */37CURLcode res = CURLE_OK;3839start_test_timing();4041global_init(CURL_GLOBAL_ALL);4243/* Allocate one curl handle per transfer */44curl = curl_easy_init();4546/* init a multi stack */47multi = curl_multi_init();4849/* add the individual transfer */50curl_multi_add_handle(multi, curl);5152/* set the options (I left out a few, you'll get the point anyway) */53curl_easy_setopt(curl, CURLOPT_URL, URL);54curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, testDataSize);55curl_easy_setopt(curl, CURLOPT_POSTFIELDS, testData);5657/* we start some action by calling perform right away */58curl_multi_perform(multi, &still_running);5960abort_on_test_timeout();6162do {63struct timeval timeout;64int rc; /* select() return code */65CURLMcode mc; /* curl_multi_fdset() return code */6667fd_set fdread;68fd_set fdwrite;69fd_set fdexcep;70int maxfd = -1;7172long curl_timeo = -1;7374FD_ZERO(&fdread);75FD_ZERO(&fdwrite);76FD_ZERO(&fdexcep);7778/* set a suitable timeout to play around with */79timeout.tv_sec = 1;80timeout.tv_usec = 0;8182curl_multi_timeout(multi, &curl_timeo);83if(curl_timeo >= 0) {84curlx_mstotv(&timeout, curl_timeo);85if(timeout.tv_sec > 1) {86timeout.tv_sec = 1;87timeout.tv_usec = 0;88}89}9091/* get file descriptors from the transfers */92mc = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);9394if(mc != CURLM_OK) {95curl_mfprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);96break;97}9899/* On success the value of maxfd is guaranteed to be >= -1. We call100select(maxfd + 1, ...); specially in case of (maxfd == -1) there are101no fds ready yet so we call select(0, ...) --or Sleep() on Windows--102to sleep 100ms, which is the minimum suggested value in the103curl_multi_fdset() doc. */104105if(maxfd == -1) {106rc = curlx_wait_ms(100);107}108else {109/* Note that on some platforms 'timeout' may be modified by select().110If you need access to the original value save a copy beforehand. */111rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);112}113114switch(rc) {115case -1:116/* select error */117break;118case 0: /* timeout */119default: /* action */120curl_multi_perform(multi, &still_running);121break;122}123124abort_on_test_timeout();125} while(still_running);126127/* See how the transfers went */128do {129msg = curl_multi_info_read(multi, &msgs_left);130if(msg && msg->msg == CURLMSG_DONE) {131curl_mprintf("HTTP transfer completed with status %d\n",132msg->data.result);133break;134}135136abort_on_test_timeout();137} while(msg);138139test_cleanup:140curl_multi_cleanup(multi);141142/* Free the curl handles */143curl_easy_cleanup(curl);144curl_global_cleanup();145146return res;147}148149150