Return to multi-app.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / docs / examples |
1.1 ! misho 1: /*************************************************************************** ! 2: * _ _ ____ _ ! 3: * Project ___| | | | _ \| | ! 4: * / __| | | | |_) | | ! 5: * | (__| |_| | _ <| |___ ! 6: * \___|\___/|_| \_\_____| ! 7: * ! 8: * Copyright (C) 1998 - 2019, 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.haxx.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: /* <DESC> ! 23: * A basic application source code using the multi interface doing two ! 24: * transfers in parallel. ! 25: * </DESC> ! 26: */ ! 27: ! 28: #include <stdio.h> ! 29: #include <string.h> ! 30: ! 31: /* somewhat unix-specific */ ! 32: #include <sys/time.h> ! 33: #include <unistd.h> ! 34: ! 35: /* curl stuff */ ! 36: #include <curl/curl.h> ! 37: ! 38: /* ! 39: * Download a HTTP file and upload an FTP file simultaneously. ! 40: */ ! 41: ! 42: #define HANDLECOUNT 2 /* Number of simultaneous transfers */ ! 43: #define HTTP_HANDLE 0 /* Index for the HTTP transfer */ ! 44: #define FTP_HANDLE 1 /* Index for the FTP transfer */ ! 45: ! 46: int main(void) ! 47: { ! 48: CURL *handles[HANDLECOUNT]; ! 49: CURLM *multi_handle; ! 50: ! 51: int still_running = 0; /* keep number of running handles */ ! 52: int i; ! 53: ! 54: CURLMsg *msg; /* for picking up messages with the transfer status */ ! 55: int msgs_left; /* how many messages are left */ ! 56: ! 57: /* Allocate one CURL handle per transfer */ ! 58: for(i = 0; i<HANDLECOUNT; i++) ! 59: handles[i] = curl_easy_init(); ! 60: ! 61: /* set the options (I left out a few, you'll get the point anyway) */ ! 62: curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "https://example.com"); ! 63: ! 64: curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com"); ! 65: curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L); ! 66: ! 67: /* init a multi stack */ ! 68: multi_handle = curl_multi_init(); ! 69: ! 70: /* add the individual transfers */ ! 71: for(i = 0; i<HANDLECOUNT; i++) ! 72: curl_multi_add_handle(multi_handle, handles[i]); ! 73: ! 74: /* we start some action by calling perform right away */ ! 75: curl_multi_perform(multi_handle, &still_running); ! 76: ! 77: while(still_running) { ! 78: struct timeval timeout; ! 79: int rc; /* select() return code */ ! 80: CURLMcode mc; /* curl_multi_fdset() return code */ ! 81: ! 82: fd_set fdread; ! 83: fd_set fdwrite; ! 84: fd_set fdexcep; ! 85: int maxfd = -1; ! 86: ! 87: long curl_timeo = -1; ! 88: ! 89: FD_ZERO(&fdread); ! 90: FD_ZERO(&fdwrite); ! 91: FD_ZERO(&fdexcep); ! 92: ! 93: /* set a suitable timeout to play around with */ ! 94: timeout.tv_sec = 1; ! 95: timeout.tv_usec = 0; ! 96: ! 97: curl_multi_timeout(multi_handle, &curl_timeo); ! 98: if(curl_timeo >= 0) { ! 99: timeout.tv_sec = curl_timeo / 1000; ! 100: if(timeout.tv_sec > 1) ! 101: timeout.tv_sec = 1; ! 102: else ! 103: timeout.tv_usec = (curl_timeo % 1000) * 1000; ! 104: } ! 105: ! 106: /* get file descriptors from the transfers */ ! 107: mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); ! 108: ! 109: if(mc != CURLM_OK) { ! 110: fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); ! 111: break; ! 112: } ! 113: ! 114: /* On success the value of maxfd is guaranteed to be >= -1. We call ! 115: select(maxfd + 1, ...); specially in case of (maxfd == -1) there are ! 116: no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- ! 117: to sleep 100ms, which is the minimum suggested value in the ! 118: curl_multi_fdset() doc. */ ! 119: ! 120: if(maxfd == -1) { ! 121: #ifdef _WIN32 ! 122: Sleep(100); ! 123: rc = 0; ! 124: #else ! 125: /* Portable sleep for platforms other than Windows. */ ! 126: struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ ! 127: rc = select(0, NULL, NULL, NULL, &wait); ! 128: #endif ! 129: } ! 130: else { ! 131: /* Note that on some platforms 'timeout' may be modified by select(). ! 132: If you need access to the original value save a copy beforehand. */ ! 133: rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); ! 134: } ! 135: ! 136: switch(rc) { ! 137: case -1: ! 138: /* select error */ ! 139: break; ! 140: case 0: /* timeout */ ! 141: default: /* action */ ! 142: curl_multi_perform(multi_handle, &still_running); ! 143: break; ! 144: } ! 145: } ! 146: ! 147: /* See how the transfers went */ ! 148: while((msg = curl_multi_info_read(multi_handle, &msgs_left))) { ! 149: if(msg->msg == CURLMSG_DONE) { ! 150: int idx; ! 151: ! 152: /* Find out which handle this message is about */ ! 153: for(idx = 0; idx<HANDLECOUNT; idx++) { ! 154: int found = (msg->easy_handle == handles[idx]); ! 155: if(found) ! 156: break; ! 157: } ! 158: ! 159: switch(idx) { ! 160: case HTTP_HANDLE: ! 161: printf("HTTP transfer completed with status %d\n", msg->data.result); ! 162: break; ! 163: case FTP_HANDLE: ! 164: printf("FTP transfer completed with status %d\n", msg->data.result); ! 165: break; ! 166: } ! 167: } ! 168: } ! 169: ! 170: curl_multi_cleanup(multi_handle); ! 171: ! 172: /* Free the CURL handles */ ! 173: for(i = 0; i<HANDLECOUNT; i++) ! 174: curl_easy_cleanup(handles[i]); ! 175: ! 176: return 0; ! 177: }