diff options
| author | Philip Prindeville <philipp_subx@redfish-solutions.com> | 2018-03-16 16:01:01 +0100 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2018-03-16 16:01:01 +0100 | 
| commit | 9434194be8cfc896b416ea17d1867725990f8bc9 (patch) | |
| tree | e0dfd8d7a432f38d614cc1f62c6fb971278c0bac /docs | |
| parent | f5700ea88baa5baeb63b7cd42bd12fb03f4e0f4e (diff) | |
examples/hiperfifo.c: improved
 * use member struct event’s instead of pointers to alloc’d struct
   events
 * simplify the cases for the mcode_or_die() function via macros;
 * make multi_timer_cb() actually do what the block comment says it
   should;
 * accept a “stop” command on the FIFO to shut down the service;
 * use cleaner notation for unused variables than the (void) hack;
 * allow following redirections (304’s);
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/examples/hiperfifo.c | 140 | 
1 files changed, 76 insertions, 64 deletions
diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c index 76bc6c1f6..3ca1ed238 100644 --- a/docs/examples/hiperfifo.c +++ b/docs/examples/hiperfifo.c @@ -66,10 +66,17 @@ callback.  #include <sys/poll.h>  #include <curl/curl.h>  #include <event2/event.h> +#include <event2/event_struct.h>  #include <fcntl.h>  #include <sys/stat.h>  #include <errno.h> +#include <sys/cdefs.h> +#ifdef __GNUC__ +#define _Unused __attribute__((unused)) +#else +#define _Unused +#endif  #define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */ @@ -78,11 +85,12 @@ callback.  typedef struct _GlobalInfo  {    struct event_base *evbase; -  struct event *fifo_event; -  struct event *timer_event; +  struct event fifo_event; +  struct event timer_event;    CURLM *multi;    int still_running;    FILE *input; +  int stopped;  } GlobalInfo; @@ -103,16 +111,42 @@ typedef struct _SockInfo    CURL *easy;    int action;    long timeout; -  struct event *ev; -  int evset; +  struct event ev;    GlobalInfo *global;  } SockInfo; +#define __case(code) \ +	case code: s = __STRING(code) + +/* Die if we get a bad CURLMcode somewhere */ +static void mcode_or_die(const char *where, CURLMcode code) +{ +  if(CURLM_OK != code) { +    const char *s; +    switch(code) { +      __case(CURLM_BAD_HANDLE); break; +      __case(CURLM_BAD_EASY_HANDLE); break; +      __case(CURLM_OUT_OF_MEMORY); break; +      __case(CURLM_INTERNAL_ERROR); break; +      __case(CURLM_UNKNOWN_OPTION); break; +      __case(CURLM_LAST); break; +      default: s = "CURLM_unknown"; break; +      __case(CURLM_BAD_SOCKET); +      fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); +      /* ignore this error */ +      return; +    } +    fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); +    exit(code); +  } +} + +  /* Update the event timer after curl_multi library calls */ -static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g) +static int multi_timer_cb(CURLM *multi _Unused, long timeout_ms, GlobalInfo *g)  {    struct timeval timeout; -  (void)multi; /* unused */ +  CURLMcode rc;    timeout.tv_sec = timeout_ms/1000;    timeout.tv_usec = (timeout_ms%1000)*1000; @@ -127,35 +161,17 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)     * for all other values of timeout_ms, this should set or *update*     * the timer to the new value     */ -  evtimer_add(g->timer_event, &timeout); +  if (timeout_ms == 0) { +    rc = curl_multi_socket_action(g->multi, +                                  CURL_SOCKET_TIMEOUT, 0, &g->still_running); +    mcode_or_die("multi_timer_cb: curl_multi_socket_action", rc); +  } else if (timeout_ms == -1) +    evtimer_del(&g->timer_event); +  else +    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) { -    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"; -        break; -    case     CURLM_BAD_SOCKET:         s = "CURLM_BAD_SOCKET"; -      fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); -      /* ignore this error */ -      return; -    } -    fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s); -    exit(code); -  } -} - -  /* Check for completed transfers, and remove their easy handles */  static void check_multi_info(GlobalInfo *g) @@ -181,6 +197,8 @@ static void check_multi_info(GlobalInfo *g)        free(conn);      }    } +  if (g->still_running == 0 && g->stopped) +    event_base_loopbreak(g->evbase);  } @@ -201,8 +219,8 @@ static void event_cb(int fd, short kind, void *userp)    check_multi_info(g);    if(g->still_running <= 0) {      fprintf(MSG_OUT, "last transfer done, kill timeout\n"); -    if(evtimer_pending(g->timer_event, NULL)) { -      evtimer_del(g->timer_event); +    if(evtimer_pending(&g->timer_event, NULL)) { +      evtimer_del(&g->timer_event);      }    }  } @@ -210,12 +228,10 @@ static void event_cb(int fd, short kind, void *userp)  /* Called by libevent when our timeout expires */ -static void timer_cb(int fd, short kind, void *userp) +static void timer_cb(int fd _Unused, short kind _Unused, void *userp)  {    GlobalInfo *g = (GlobalInfo *)userp;    CURLMcode rc; -  (void)fd; -  (void)kind;    rc = curl_multi_socket_action(g->multi,                                    CURL_SOCKET_TIMEOUT, 0, &g->still_running); @@ -229,8 +245,7 @@ static void timer_cb(int fd, short kind, void *userp)  static void remsock(SockInfo *f)  {    if(f) { -    if(f->evset) -      event_free(f->ev); +    event_del(&f->ev);      free(f);    }  } @@ -247,11 +262,9 @@ static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,    f->sockfd = s;    f->action = act;    f->easy = e; -  if(f->evset) -    event_free(f->ev); -  f->ev = event_new(g->evbase, f->sockfd, kind, event_cb, g); -  f->evset = 1; -  event_add(f->ev, NULL); +  event_del(&f->ev); +  event_assign(&f->ev, g->evbase, f->sockfd, kind, event_cb, g); +  event_add(&f->ev, NULL);  } @@ -297,23 +310,20 @@ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)  /* CURLOPT_WRITEFUNCTION */ -static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data) +static size_t write_cb(void *ptr _Unused, size_t size, size_t nmemb, void *data)  {    size_t realsize = size * nmemb; -  ConnInfo *conn = (ConnInfo*) data; -  (void)ptr; -  (void)conn; +  ConnInfo *conn _Unused = (ConnInfo*) data; +    return realsize;  }  /* 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 _Unused, +                   double uln _Unused)  {    ConnInfo *conn = (ConnInfo *)p; -  (void)ult; -  (void)uln;    fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);    return 0; @@ -346,6 +356,7 @@ static void new_conn(char *url, GlobalInfo *g)    curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);    curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);    curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); +  curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);    fprintf(MSG_OUT,            "Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);    rc = curl_multi_add_handle(g->multi, conn->easy); @@ -356,21 +367,24 @@ static void new_conn(char *url, GlobalInfo *g)  }  /* This gets called whenever data is received from the fifo */ -static void fifo_cb(int fd, short event, void *arg) +static void fifo_cb(int fd _Unused, short event _Unused, void *arg)  {    char s[1024];    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);      s[n]='\0';      if(n && s[0]) { -      new_conn(s, arg);  /* if we read a URL, go get it! */ +      if (!strcmp(s, "stop")) { +        g->stopped = 1; +	if (g->still_running == 0) +          event_base_loopbreak(g->evbase); +      } else +        new_conn(s, arg);  /* if we read a URL, go get it! */      }      else        break; @@ -405,29 +419,27 @@ static int init_fifo(GlobalInfo *g)    g->input = fdopen(sockfd, "r");    fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo); -  g->fifo_event = event_new(g->evbase, sockfd, EV_READ|EV_PERSIST, fifo_cb, g); -  event_add(g->fifo_event, NULL); +  event_assign(&g->fifo_event, g->evbase, sockfd, EV_READ|EV_PERSIST, fifo_cb, g); +  event_add(&g->fifo_event, NULL);    return (0);  }  static void clean_fifo(GlobalInfo *g)  { -    event_free(g->fifo_event); +    event_del(&g->fifo_event);      fclose(g->input);      unlink(fifo);  } -int main(int argc, char **argv) +int main(int argc _Unused, char **argv _Unused)  {    GlobalInfo g; -  (void)argc; -  (void)argv;    memset(&g, 0, sizeof(GlobalInfo));    g.evbase = event_base_new();    init_fifo(&g);    g.multi = curl_multi_init(); -  g.timer_event = evtimer_new(g.evbase, timer_cb, &g); +  evtimer_assign(&g.timer_event, g.evbase, timer_cb, &g);    /* setup the generic multi interface options we want */    curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb); @@ -443,7 +455,7 @@ int main(int argc, char **argv)    /* this, of course, won't get called since only way to stop this program is       via ctrl-C, but it is here to show how cleanup /would/ be done. */    clean_fifo(&g); -  event_free(g.timer_event); +  event_del(&g.timer_event);    event_base_free(g.evbase);    curl_multi_cleanup(g.multi);    return 0;  | 
