1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*************************************************************************** 29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * _ _ ____ _ 39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Project ___| | | | _ \| | 49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * / __| | | | |_) | | 59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | (__| |_| | _ <| |___ 69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * \___|\___/|_| \_\_____| 79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. 99bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which 11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms 12e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * are also available at http://curl.haxx.se/docs/copyright.html. 13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is 16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file. 17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied. 20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/ 22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Example application source code using the multi socket interface to 239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * download many files at once. 249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This example features the same basic functionality as hiperfifo.c does, 269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * but this uses libev instead of libevent. 279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Written by Jeff Pohlmeyer, converted to use libev by Markus Koetter 299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsRequires libev and a (POSIX?) system that has mkfifo(). 319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsThis is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c" 339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelssample programs. 349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsWhen running, the program creates the named pipe "hiper.fifo" 369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsWhenever there is input into the fifo, the program reads the input as a list 389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsof URL's and creates some new easy handles to fetch each URL via the 399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_multi "hiper" API. 409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsThus, you can try a single URL: 439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels % echo http://www.yahoo.com > hiper.fifo 449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsOr a whole bunch of them: 469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels % cat my-url-list > hiper.fifo 479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsThe fifo buffer is handled almost instantly, so you can even add more URL's 499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelswhile the previous requests are still being downloaded. 509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsNote: 529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels For the sake of simplicity, URL length is limited to 1023 char's ! 539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas EckelsThis is purely a demo app, all retrieved data is simply discarded by the write 559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscallback. 569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels*/ 589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <stdio.h> 609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <string.h> 619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <stdlib.h> 629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <sys/time.h> 639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <time.h> 649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <unistd.h> 659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <sys/poll.h> 669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <curl/curl.h> 679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <ev.h> 689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <fcntl.h> 699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <sys/stat.h> 709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include <errno.h> 719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define DPRINT(x...) printf(x) 739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */ 759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Global information, common to all connections */ 789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelstypedef struct _GlobalInfo 799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct ev_loop *loop; 819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct ev_io fifo_event; 829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct ev_timer timer_event; 839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLM *multi; 849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int still_running; 859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels FILE* input; 869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} GlobalInfo; 879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Information associated with a specific easy handle */ 909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelstypedef struct _ConnInfo 919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURL *easy; 939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *url; 949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo *global; 959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char error[CURL_ERROR_SIZE]; 969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} ConnInfo; 979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Information associated with a specific socket */ 1009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelstypedef struct _SockInfo 1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_socket_t sockfd; 1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURL *easy; 1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int action; 1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels long timeout; 1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct ev_io ev; 1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int evset; 1089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo *global; 1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} SockInfo; 1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void timer_cb(EV_P_ struct ev_timer *w, int revents); 1129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Update the event timer after curl_multi library calls */ 1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) 1159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms); 1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_timer_stop(g->loop, &g->timer_event); 1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if (timeout_ms > 0) 1199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels double t = timeout_ms / 1000; 1219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_timer_init(&g->timer_event, timer_cb, t, 0.); 1229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_timer_start(g->loop, &g->timer_event); 1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels }else 1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels timer_cb(g->loop, &g->timer_event, 0); 1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 0; 1269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Die if we get a bad CURLMcode somewhere */ 1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void mcode_or_die(const char *where, CURLMcode code) 1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( CURLM_OK != code ) 1329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels const char *s; 1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels switch ( code ) 1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 1369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break; 1379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break; 1389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break; 1399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break; 1409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break; 1419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_LAST: s="CURLM_LAST"; break; 1429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels default: s="CURLM_unknown"; 1439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 1449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; 1459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); 1469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* ignore this error */ 1479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return; 1489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); 1509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels exit(code); 1519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Check for completed transfers, and remove their easy handles */ 1579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void check_multi_info(GlobalInfo *g) 1589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *eff_url; 1609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLMsg *msg; 1619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int msgs_left; 1629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ConnInfo *conn; 1639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURL *easy; 1649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLcode res; 1659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running); 1679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { 1689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if (msg->msg == CURLMSG_DONE) { 1699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels easy = msg->easy_handle; 1709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels res = msg->data.result; 1719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); 1729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); 1739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error); 1749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_remove_handle(g->multi, easy); 1759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(conn->url); 1769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_cleanup(easy); 1779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(conn); 1789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Called by libevent when we get action on a multi socket */ 1859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void event_cb(EV_P_ struct ev_io *w, int revents) 1869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 1879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents); 1889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo *g = (GlobalInfo*) w->data; 1899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLMcode rc; 1909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int action = (revents&EV_READ?CURL_POLL_IN:0)| 1929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (revents&EV_WRITE?CURL_POLL_OUT:0); 1939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running); 1949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels mcode_or_die("event_cb: curl_multi_socket_action", rc); 1959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels check_multi_info(g); 1969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( g->still_running <= 0 ) 1979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 1989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "last transfer done, kill timeout\n"); 1999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_timer_stop(g->loop, &g->timer_event); 2009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Called by libevent when our timeout expires */ 2049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void timer_cb(EV_P_ struct ev_timer *w, int revents) 2059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents); 2079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo *g = (GlobalInfo *)w->data; 2099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLMcode rc; 2109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running); 2129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels mcode_or_die("timer_cb: curl_multi_socket_action", rc); 2139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels check_multi_info(g); 2149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Clean up the SockInfo structure */ 2179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void remsock(SockInfo *f, GlobalInfo *g) 2189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels printf("%s \n", __PRETTY_FUNCTION__); 2209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( f ) 2219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 2229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( f->evset ) 2239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_io_stop(g->loop, &f->ev); 2249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(f); 2259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Assign information to a SockInfo structure */ 2319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g) 2329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels printf("%s \n", __PRETTY_FUNCTION__); 2349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int kind = (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0); 2369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels f->sockfd = s; 2389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels f->action = act; 2399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels f->easy = e; 2409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( f->evset ) 2419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_io_stop(g->loop, &f->ev); 2429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_io_init(&f->ev, event_cb, f->sockfd, kind); 2439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels f->ev.data = g; 2449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels f->evset=1; 2459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_io_start(g->loop, &f->ev); 2469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Initialize a new SockInfo structure */ 2519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) 2529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels SockInfo *fdp = calloc(sizeof(SockInfo), 1); 2549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fdp->global = g; 2569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels setsock(fdp, s, easy, action, g); 2579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_assign(g->multi, s, fdp); 2589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* CURLMOPT_SOCKETFUNCTION */ 2619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) 2629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels DPRINT("%s e %p s %i what %i cbp %p sockp %p\n", 2649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels __PRETTY_FUNCTION__, e, s, what, cbp, sockp); 2659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo *g = (GlobalInfo*) cbp; 2679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels SockInfo *fdp = (SockInfo*) sockp; 2689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"}; 2699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, 2719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); 2729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( what == CURL_POLL_REMOVE ) 2739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 2749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "\n"); 2759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels remsock(fdp, g); 2769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } else 2779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 2789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( !fdp ) 2799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 2809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]); 2819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels addsock(s, e, what, g); 2829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } else 2839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 2849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, 2859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "Changing action from %s to %s\n", 2869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels whatstr[fdp->action], whatstr[what]); 2879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels setsock(fdp, s, e, what, g); 2889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 0; 2919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* CURLOPT_WRITEFUNCTION */ 2959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) 2969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t realsize = size * nmemb; 2989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ConnInfo *conn = (ConnInfo*) data; 2999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)ptr; 3009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)conn; 3019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return realsize; 3029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 3039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* CURLOPT_PROGRESSFUNCTION */ 3069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic int prog_cb (void *p, double dltotal, double dlnow, double ult, 3079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels double uln) 3089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 3099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ConnInfo *conn = (ConnInfo *)p; 3109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)ult; 3119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)uln; 3129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal); 3149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 0; 3159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 3169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Create a new easy handle, and add it to the global curl_multi */ 3199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void new_conn(char *url, GlobalInfo *g ) 3209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 3219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ConnInfo *conn; 3229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLMcode rc; 3239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn = calloc(1, sizeof(ConnInfo)); 3259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memset(conn, 0, sizeof(ConnInfo)); 3269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->error[0]='\0'; 3279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->easy = curl_easy_init(); 3299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( !conn->easy ) 3309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 3319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n"); 3329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels exit(2); 3339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->global = g; 3359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels conn->url = strdup(url); 3369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); 3379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); 338e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn); 3399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L); 3409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); 3419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); 3429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L); 3439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); 3449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); 3459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L); 3469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L); 3479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, 3499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels "Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); 3509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rc = curl_multi_add_handle(g->multi, conn->easy); 3519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels mcode_or_die("new_conn: curl_multi_add_handle", rc); 3529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* note that the add_handle() will set a time-out to trigger very soon so 3549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels that the necessary socket_action() call will be called by this app */ 3559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 3569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* This gets called whenever data is received from the fifo */ 3589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic void fifo_cb(EV_P_ struct ev_io *w, int revents) 3599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 3609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char s[1024]; 3619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels long int rv=0; 3629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int n=0; 3639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo *g = (GlobalInfo *)w->data; 3649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels do 3669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 3679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels s[0]='\0'; 3689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels rv=fscanf(g->input, "%1023s%n", s, &n); 3699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels s[n]='\0'; 3709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( n && s[0] ) 3719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 3729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels new_conn(s,g); /* if we read a URL, go get it! */ 3739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } else break; 3749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } while ( rv != EOF ); 3759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 3769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* Create a named pipe and tell libevent to monitor it */ 3789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic int init_fifo (GlobalInfo *g) 3799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 3809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels struct stat st; 3819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels static const char *fifo = "hiper.fifo"; 382e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_socket_t sockfd; 3839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo); 3859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( lstat (fifo, &st) == 0 ) 3869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 3879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( (st.st_mode & S_IFMT) == S_IFREG ) 3889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 3899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels errno = EEXIST; 3909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels perror("lstat"); 3919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels exit (1); 3929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels unlink(fifo); 3959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( mkfifo (fifo, 0600) == -1 ) 3969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 3979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels perror("mkfifo"); 3989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels exit (1); 3999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0); 4019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if ( sockfd == -1 ) 4029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels { 4039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels perror("open"); 4049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels exit (1); 4059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels g->input = fdopen(sockfd, "r"); 4079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo); 4099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ); 4109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_io_start(g->loop, &g->fifo_event); 4119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return(0); 4129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 4139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint main(int argc, char **argv) 4159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 4169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels GlobalInfo g; 4179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels CURLMcode rc; 4189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)argc; 4199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels (void)argv; 4209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memset(&g, 0, sizeof(GlobalInfo)); 4229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels g.loop = ev_default_loop(0); 4239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels init_fifo(&g); 4259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels g.multi = curl_multi_init(); 4269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_timer_init(&g.timer_event, timer_cb, 0., 0.); 4289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels g.timer_event.data = &g; 4299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels g.fifo_event.data = &g; 4309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb); 4319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g); 4329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb); 4339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g); 4349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* we don't call any curl_multi_socket*() function yet as we have no handles 4369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels added! */ 4379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ev_loop(g.loop, 0); 4399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels curl_multi_cleanup(g.multi); 4409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return 0; 4419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 442