* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* KIND, either express or implied.
*
***************************************************************************/
+/* <DESC>
+ * multi socket API usage with libevent 2
+ * </DESC>
+ */
/* Example application source code using the multi socket interface to
download many files at once.
struct event *timer_event;
CURLM *multi;
int still_running;
- FILE* input;
+ FILE *input;
} GlobalInfo;
GlobalInfo *global;
} SockInfo;
-
-
/* Update the event timer after curl_multi library calls */
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
{
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
+
+ /* TODO
+ *
+ * if timeout_ms is 0, call curl_multi_socket_action() at once!
+ *
+ * if timeout_ms is -1, just delete the timer
+ *
+ * for all other values of timeout_ms, this should set or *update*
+ * the timer to the new value
+ */
evtimer_add(g->timer_event, &timeout);
return 0;
}
/* Die if we get a bad CURLMcode somewhere */
static void mcode_or_die(const char *where, CURLMcode code)
{
- if ( CURLM_OK != code ) {
+ if(CURLM_OK != code) {
const char *s;
- switch (code) {
- case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
- case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
- case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
- case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
- case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
- case CURLM_LAST: s="CURLM_LAST"; break;
- default: s="CURLM_unknown";
+ switch(code) {
+ case CURLM_BAD_HANDLE: s = "CURLM_BAD_HANDLE"; break;
+ case CURLM_BAD_EASY_HANDLE: s = "CURLM_BAD_EASY_HANDLE"; break;
+ case CURLM_OUT_OF_MEMORY: s = "CURLM_OUT_OF_MEMORY"; break;
+ case CURLM_INTERNAL_ERROR: s = "CURLM_INTERNAL_ERROR"; break;
+ case CURLM_UNKNOWN_OPTION: s = "CURLM_UNKNOWN_OPTION"; break;
+ case CURLM_LAST: s = "CURLM_LAST"; break;
+ default: s = "CURLM_unknown";
break;
- case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
+ case CURLM_BAD_SOCKET: s = "CURLM_BAD_SOCKET";
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
/* ignore this error */
return;
CURLcode res;
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
- while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
- if (msg->msg == CURLMSG_DONE) {
+ while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
+ if(msg->msg == CURLMSG_DONE) {
easy = msg->easy_handle;
res = msg->data.result;
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
mcode_or_die("event_cb: curl_multi_socket_action", rc);
check_multi_info(g);
- if ( g->still_running <= 0 ) {
+ if(g->still_running <= 0) {
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
- if (evtimer_pending(g->timer_event, NULL)) {
+ if(evtimer_pending(g->timer_event, NULL)) {
evtimer_del(g->timer_event);
}
}
/* Clean up the SockInfo structure */
static void remsock(SockInfo *f)
{
- if (f) {
- if (f->evset)
+ if(f) {
+ if(f->evset)
event_free(f->ev);
free(f);
}
/* Assign information to a SockInfo structure */
-static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
+ GlobalInfo *g)
{
int kind =
(act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
f->sockfd = s;
f->action = act;
f->easy = e;
- if (f->evset)
+ if(f->evset)
event_free(f->ev);
f->ev = event_new(g->evbase, f->sockfd, kind, event_cb, g);
f->evset = 1;
fprintf(MSG_OUT,
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
- if (what == CURL_POLL_REMOVE) {
+ if(what == CURL_POLL_REMOVE) {
fprintf(MSG_OUT, "\n");
remsock(fdp);
}
else {
- if (!fdp) {
+ if(!fdp) {
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
addsock(s, e, what, g);
}
/* CURLOPT_PROGRESSFUNCTION */
-static int prog_cb (void *p, double dltotal, double dlnow, double ult,
- double uln)
+static int prog_cb(void *p, double dltotal, double dlnow, double ult,
+ double uln)
{
ConnInfo *conn = (ConnInfo *)p;
(void)ult;
/* Create a new easy handle, and add it to the global curl_multi */
-static void new_conn(char *url, GlobalInfo *g )
+static void new_conn(char *url, GlobalInfo *g)
{
ConnInfo *conn;
CURLMcode rc;
conn->error[0]='\0';
conn->easy = curl_easy_init();
- if (!conn->easy) {
+ if(!conn->easy) {
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
exit(2);
}
conn->url = strdup(url);
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
- curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
static void fifo_cb(int fd, short event, void *arg)
{
char s[1024];
- long int rv=0;
- int n=0;
+ long int rv = 0;
+ int n = 0;
GlobalInfo *g = (GlobalInfo *)arg;
(void)fd; /* unused */
(void)event; /* unused */
do {
s[0]='\0';
- rv=fscanf(g->input, "%1023s%n", s, &n);
+ rv = fscanf(g->input, "%1023s%n", s, &n);
s[n]='\0';
- if ( n && s[0] ) {
- new_conn(s,arg); /* if we read a URL, go get it! */
- } else break;
- } while ( rv != EOF);
+ if(n && s[0]) {
+ new_conn(s, arg); /* if we read a URL, go get it! */
+ }
+ else
+ break;
+ } while(rv != EOF);
}
/* Create a named pipe and tell libevent to monitor it */
static const char *fifo = "hiper.fifo";
-static int init_fifo (GlobalInfo *g)
+static int init_fifo(GlobalInfo *g)
{
struct stat st;
curl_socket_t sockfd;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
- if (lstat (fifo, &st) == 0) {
- if ((st.st_mode & S_IFMT) == S_IFREG) {
+ if(lstat (fifo, &st) == 0) {
+ if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
- exit (1);
+ exit(1);
}
}
unlink(fifo);
- if (mkfifo (fifo, 0600) == -1) {
+ if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
- exit (1);
+ exit(1);
}
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
- if (sockfd == -1) {
+ if(sockfd == -1) {
perror("open");
- exit (1);
+ exit(1);
}
g->input = fdopen(sockfd, "r");