examples: omit forward declarations, apply misc fixes
No binary (build failed)
—
(log yok)
| @@ -110,7 +110,7 @@ static struct ip *ip_list_append(struct ip *list, const char *data) | |
| struct ip *ip, *last; | |
| char *cidr; | |
| - | ip = (struct ip *)calloc(1, sizeof(*ip)); |
| + | ip = calloc(1, sizeof(*ip)); |
| if(!ip) | |
| return NULL; | |
| @@ -296,7 +296,7 @@ int main(void) | |
| CURLcode result; | |
| struct connection_filter *filter; | |
| - | filter = (struct connection_filter *)calloc(1, sizeof(*filter)); |
| + | filter = calloc(1, sizeof(*filter)); |
| if(!filter) | |
| return 1; | |
| @@ -22,7 +22,7 @@ | |
| * | |
| ***************************************************************************/ | |
| /* <DESC> | |
| - | * multi socket API usage with epoll and timerfd |
| + | * multi socket interface with epoll and timerfd |
| * </DESC> | |
| */ | |
| /* Example application source code using the multi socket interface to | |
| @@ -140,40 +140,6 @@ static void mcode_or_die(const char *where, CURLMcode code) | |
| } | |
| } | |
| - | static void timer_cb(struct GlobalInfo *g, int revents); |
| - | |
| - | /* Update the timer after curl_multi library does its thing. curl informs the |
| - | * application through this callback what it wants the new timeout to be, |
| - | * after it does some work. */ |
| - | static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) |
| - | { |
| - | struct itimerspec its; |
| - | |
| - | fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms); |
| - | |
| - | if(timeout_ms > 0) { |
| - | its.it_interval.tv_sec = 0; |
| - | its.it_interval.tv_nsec = 0; |
| - | its.it_value.tv_sec = timeout_ms / 1000; |
| - | its.it_value.tv_nsec = (timeout_ms % 1000) * 1000 * 1000; |
| - | } |
| - | else if(timeout_ms == 0) { |
| - | /* libcurl wants us to timeout now, however setting both fields of |
| - | * new_value.it_value to zero disarms the timer. The closest we can |
| - | * do is to schedule the timer to fire in 1 ns. */ |
| - | its.it_interval.tv_sec = 0; |
| - | its.it_interval.tv_nsec = 0; |
| - | its.it_value.tv_sec = 0; |
| - | its.it_value.tv_nsec = 1; |
| - | } |
| - | else { |
| - | memset(&its, 0, sizeof(its)); |
| - | } |
| - | |
| - | timerfd_settime(g->tfd, /* flags= */ 0, &its, NULL); |
| - | return 0; |
| - | } |
| - | |
| /* Check for completed transfers, and remove their easy handles */ | |
| static void check_multi_info(struct GlobalInfo *g) | |
| { | |
| @@ -198,26 +164,6 @@ static void check_multi_info(struct GlobalInfo *g) | |
| } | |
| } | |
| - | /* Called by libevent when we get action on a multi socket filedescriptor */ |
| - | static void event_cb(struct GlobalInfo *g, int fd, int revents) |
| - | { |
| - | CURLMcode mresult; |
| - | struct itimerspec its; |
| - | |
| - | int action = ((revents & EPOLLIN) ? CURL_CSELECT_IN : 0) | |
| - | ((revents & EPOLLOUT) ? CURL_CSELECT_OUT : 0); |
| - | |
| - | mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running); |
| - | mcode_or_die("event_cb: curl_multi_socket_action", mresult); |
| - | |
| - | check_multi_info(g); |
| - | if(g->still_running <= 0) { |
| - | fprintf(MSG_OUT, "last transfer done, kill timeout\n"); |
| - | memset(&its, 0, sizeof(its)); |
| - | timerfd_settime(g->tfd, 0, &its, NULL); |
| - | } |
| - | } |
| - | |
| /* Called by main loop when our timeout expires */ | |
| static void timer_cb(struct GlobalInfo *g, int revents) | |
| { | |
| @@ -225,6 +171,8 @@ static void timer_cb(struct GlobalInfo *g, int revents) | |
| uint64_t count = 0; | |
| ssize_t err = 0; | |
| + | (void)revents; |
| + | |
| err = read(g->tfd, &count, sizeof(uint64_t)); | |
| if(err == -1) { | |
| /* Note that we may call the timer callback even if the timerfd is not | |
| @@ -242,12 +190,66 @@ static void timer_cb(struct GlobalInfo *g, int revents) | |
| perror("read(tfd)"); | |
| } | |
| - | mresult = curl_multi_socket_action(g->multi, |
| - | CURL_SOCKET_TIMEOUT, 0, &g->still_running); |
| + | mresult = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, |
| + | &g->still_running); |
| mcode_or_die("timer_cb: curl_multi_socket_action", mresult); | |
| check_multi_info(g); | |
| } | |
| + | /* Update the timer after curl_multi library does its thing. curl informs the |
| + | * application through this callback what it wants the new timeout to be, |
| + | * after it does some work. */ |
| + | static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) |
| + | { |
| + | struct itimerspec its; |
| + | |
| + | (void)multi; |
| + | |
| + | fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms); |
| + | |
| + | if(timeout_ms > 0) { |
| + | its.it_interval.tv_sec = 0; |
| + | its.it_interval.tv_nsec = 0; |
| + | its.it_value.tv_sec = timeout_ms / 1000; |
| + | its.it_value.tv_nsec = (timeout_ms % 1000) * 1000 * 1000; |
| + | } |
| + | else if(timeout_ms == 0) { |
| + | /* libcurl wants us to timeout now, however setting both fields of |
| + | * new_value.it_value to zero disarms the timer. The closest we can |
| + | * do is to schedule the timer to fire in 1 ns. */ |
| + | its.it_interval.tv_sec = 0; |
| + | its.it_interval.tv_nsec = 0; |
| + | its.it_value.tv_sec = 0; |
| + | its.it_value.tv_nsec = 1; |
| + | } |
| + | else { |
| + | memset(&its, 0, sizeof(its)); |
| + | } |
| + | |
| + | timerfd_settime(g->tfd, /* flags= */ 0, &its, NULL); |
| + | return 0; |
| + | } |
| + | |
| + | /* Called by libevent when we get action on a multi socket filedescriptor */ |
| + | static void event_cb(struct GlobalInfo *g, int fd, int revents) |
| + | { |
| + | CURLMcode mresult; |
| + | struct itimerspec its; |
| + | |
| + | int action = ((revents & EPOLLIN) ? CURL_CSELECT_IN : 0) | |
| + | ((revents & EPOLLOUT) ? CURL_CSELECT_OUT : 0); |
| + | |
| + | mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running); |
| + | mcode_or_die("event_cb: curl_multi_socket_action", mresult); |
| + | |
| + | check_multi_info(g); |
| + | if(g->still_running <= 0) { |
| + | fprintf(MSG_OUT, "last transfer done, kill timeout\n"); |
| + | memset(&its, 0, sizeof(its)); |
| + | timerfd_settime(g->tfd, 0, &its, NULL); |
| + | } |
| + | } |
| + | |
| /* Clean up the SockInfo structure */ | |
| static void remsock(struct SockInfo *f, struct GlobalInfo *g) | |
| { | |
| @@ -290,7 +292,7 @@ static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, | |
| static void addsock(curl_socket_t s, CURL *curl, int action, | |
| struct GlobalInfo *g) | |
| { | |
| - | struct SockInfo *fdp = (struct SockInfo *)calloc(1, sizeof(struct SockInfo)); |
| + | struct SockInfo *fdp = calloc(1, sizeof(struct SockInfo)); |
| fdp->global = g; | |
| setsock(fdp, s, curl, action, g); | |
| @@ -349,7 +351,7 @@ static void new_conn(const char *url, struct GlobalInfo *g) | |
| struct ConnInfo *conn; | |
| CURLMcode mresult; | |
| - | conn = (struct ConnInfo *)calloc(1, sizeof(*conn)); |
| + | conn = calloc(1, sizeof(*conn)); |
| conn->error[0] = '\0'; | |
| conn->curl = curl_easy_init(); | |
| @@ -371,13 +373,14 @@ static void new_conn(const char *url, struct GlobalInfo *g) | |
| curl_easy_setopt(conn->curl, CURLOPT_FOLLOWLOCATION, 1L); | |
| curl_easy_setopt(conn->curl, CURLOPT_LOW_SPEED_TIME, 3L); | |
| curl_easy_setopt(conn->curl, CURLOPT_LOW_SPEED_LIMIT, 10L); | |
| + | |
| fprintf(MSG_OUT, "Adding easy %p to multi %p (%s)\n", | |
| conn->curl, g->multi, url); | |
| mresult = curl_multi_add_handle(g->multi, conn->curl); | |
| mcode_or_die("new_conn: curl_multi_add_handle", mresult); | |
| - | /* note that the add_handle() sets a timeout to trigger soon so that the |
| - | * necessary socket_action() call gets called by this app */ |
| + | /* note that add_handle() sets a timeout to trigger soon so that the |
| + | necessary socket_action() gets called */ |
| } | |
| /* This gets called whenever data is received from the fifo */ | |
| @@ -387,6 +390,8 @@ static void fifo_cb(struct GlobalInfo *g, int revents) | |
| long int rv = 0; | |
| int n = 0; | |
| + | (void)revents; |
| + | |
| do { | |
| s[0] = '\0'; | |
| rv = fscanf(g->input, "%1023s%n", s, &n); | |
| @@ -400,10 +405,10 @@ static void fifo_cb(struct GlobalInfo *g, int revents) | |
| } | |
| /* Create a named pipe and tell libevent to monitor it */ | |
| - | static const char *fifo = "hiper.fifo"; |
| static int init_fifo(struct GlobalInfo *g) | |
| { | |
| struct stat st; | |
| + | static const char *fifo = "hiper.fifo"; |
| curl_socket_t sockfd; | |
| struct epoll_event epev; | |
| @@ -22,7 +22,7 @@ | |
| * | |
| ***************************************************************************/ | |
| /* <DESC> | |
| - | * multi socket interface together with libev |
| + | * multi socket interface with libev |
| * </DESC> | |
| */ | |
| /* Example application source code using the multi socket interface to | |
| @@ -106,23 +106,6 @@ struct SockInfo { | |
| struct GlobalInfo *global; | |
| }; | |
| - | static void timer_cb(EV_P_ struct ev_timer *w, int revents); |
| - | |
| - | /* Update the event timer after curl_multi library calls */ |
| - | static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) |
| - | { |
| - | (void)multi; |
| - | printf("%s %li\n", __PRETTY_FUNCTION__, timeout_ms); |
| - | ev_timer_stop(g->loop, &g->timer_event); |
| - | if(timeout_ms >= 0) { |
| - | /* -1 means delete, other values are timeout times in milliseconds */ |
| - | double t = timeout_ms / 1000; |
| - | ev_timer_init(&g->timer_event, timer_cb, t, 0.); |
| - | ev_timer_start(g->loop, &g->timer_event); |
| - | } |
| - | return 0; |
| - | } |
| - | |
| /* Die if we get a bad CURLMcode somewhere */ | |
| static void mcode_or_die(const char *where, CURLMcode code) | |
| { | |
| @@ -185,42 +168,57 @@ static void check_multi_info(struct GlobalInfo *g) | |
| } | |
| } | |
| - | /* Called by libevent when we get action on a multi socket */ |
| - | static void event_cb(EV_P_ struct ev_io *w, int revents) |
| + | /* Called by libevent when our timeout expires */ |
| + | static void timer_cb(EV_P_ struct ev_timer *w, int revents) |
| { | |
| - | struct GlobalInfo *g; |
| CURLMcode mresult; | |
| - | int action; |
| + | struct GlobalInfo *g; |
| printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents); | |
| + | |
| g = (struct GlobalInfo *)w->data; | |
| - | action = ((revents & EV_READ) ? CURL_POLL_IN : 0) | |
| - | ((revents & EV_WRITE) ? CURL_POLL_OUT : 0); |
| - | mresult = curl_multi_socket_action(g->multi, w->fd, action, |
| + | mresult = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, |
| &g->still_running); | |
| - | mcode_or_die("event_cb: curl_multi_socket_action", mresult); |
| + | mcode_or_die("timer_cb: curl_multi_socket_action", mresult); |
| check_multi_info(g); | |
| - | if(g->still_running <= 0) { |
| - | fprintf(MSG_OUT, "last transfer done, kill timeout\n"); |
| - | ev_timer_stop(g->loop, &g->timer_event); |
| + | } |
| + | |
| + | /* Update the event timer after curl_multi library calls */ |
| + | static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g) |
| + | { |
| + | (void)multi; |
| + | printf("%s %li\n", __PRETTY_FUNCTION__, timeout_ms); |
| + | ev_timer_stop(g->loop, &g->timer_event); |
| + | if(timeout_ms >= 0) { |
| + | /* -1 means delete, other values are timeout times in milliseconds */ |
| + | double t = timeout_ms / 1000; |
| + | ev_timer_init(&g->timer_event, timer_cb, t, 0.); |
| + | ev_timer_start(g->loop, &g->timer_event); |
| } | |
| + | return 0; |
| } | |
| - | /* Called by libevent when our timeout expires */ |
| - | static void timer_cb(EV_P_ struct ev_timer *w, int revents) |
| + | /* Called by libevent when we get action on a multi socket */ |
| + | static void event_cb(EV_P_ struct ev_io *w, int revents) |
| { | |
| - | struct GlobalInfo *g; |
| CURLMcode mresult; | |
| + | struct GlobalInfo *g; |
| - | printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents); |
| + | int action = ((revents & EV_READ) ? CURL_POLL_IN : 0) | |
| + | ((revents & EV_WRITE) ? CURL_POLL_OUT : 0); |
| + | printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents); |
| g = (struct GlobalInfo *)w->data; | |
| - | mresult = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, |
| - | &g->still_running); |
| - | mcode_or_die("timer_cb: curl_multi_socket_action", mresult); |
| + | mresult = curl_multi_socket_action(g->multi, w->fd, action, |
| + | &g->still_running); |
| + | mcode_or_die("event_cb: curl_multi_socket_action", mresult); |
| check_multi_info(g); | |
| + | if(g->still_running <= 0) { |
| + | fprintf(MSG_OUT, "last transfer done, kill timeout\n"); |
| + | ev_timer_stop(g->loop, &g->timer_event); |
| + | } |
| } | |
| /* Clean up the SockInfo structure */ | |
| @@ -370,7 +368,7 @@ static void fifo_cb(EV_P_ struct ev_io *w, int revents) | |
| rv = fscanf(g->input, "%1023s%n", s, &n); | |
| s[n] = '\0'; | |
| if(n && s[0]) { | |
| - | new_conn(s, g); /* if we read a URL, go get it! */ |
| + | new_conn(s, g); /* if we read a URL, go get it! */ |
| } | |
| else | |
| break; | |
| @@ -22,7 +22,7 @@ | |
| * | |
| ***************************************************************************/ | |
| /* <DESC> | |
| - | * multi socket API usage together with glib2 |
| + | * multi socket API usage with glib2 |
| * </DESC> | |
| */ | |
| /* Example application source code using the multi socket interface to | |
| @@ -194,9 +194,8 @@ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) | |
| CURLMcode mresult; | |
| int fd = g_io_channel_unix_get_fd(ch); | |
| - | int action = |
| - | ((condition & G_IO_IN) ? CURL_CSELECT_IN : 0) | |
| - | ((condition & G_IO_OUT) ? CURL_CSELECT_OUT : 0); |
| + | int action = ((condition & G_IO_IN) ? CURL_CSELECT_IN : 0) | |
| + | ((condition & G_IO_OUT) ? CURL_CSELECT_OUT : 0); |
| mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running); | |
| mcode_or_die("event_cb: curl_multi_socket_action", mresult); | |
| @@ -230,9 +229,8 @@ static void remsock(struct SockInfo *f) | |
| static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, | |
| struct GlobalInfo *g) | |
| { | |
| - | GIOCondition kind = |
| - | ((act & CURL_POLL_IN) ? G_IO_IN : 0) | |
| - | ((act & CURL_POLL_OUT) ? G_IO_OUT : 0); |
| + | GIOCondition kind = ((act & CURL_POLL_IN) ? G_IO_IN : 0) | |
| + | ((act & CURL_POLL_OUT) ? G_IO_OUT : 0); |
| f->sockfd = s; | |
| f->action = act; | |
| @@ -198,9 +198,8 @@ static void event_cb(int fd, short kind, void *userp) | |
| struct GlobalInfo *g = (struct GlobalInfo *)userp; | |
| CURLMcode mresult; | |
| - | int action = |
| - | ((kind & EV_READ) ? CURL_CSELECT_IN : 0) | |
| - | ((kind & EV_WRITE) ? CURL_CSELECT_OUT : 0); |
| + | int action = ((kind & EV_READ) ? CURL_CSELECT_IN : 0) | |
| + | ((kind & EV_WRITE) ? CURL_CSELECT_OUT : 0); |
| mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running); | |
| mcode_or_die("event_cb: curl_multi_socket_action", mresult); | |
| @@ -243,9 +242,8 @@ static void remsock(struct SockInfo *f) | |
| static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act, | |
| struct GlobalInfo *g) | |
| { | |
| - | int kind = |
| - | ((act & CURL_POLL_IN) ? EV_READ : 0) | |
| - | ((act & CURL_POLL_OUT) ? EV_WRITE : 0) | EV_PERSIST; |
| + | int kind = ((act & CURL_POLL_IN) ? EV_READ : 0) | |
| + | ((act & CURL_POLL_OUT) ? EV_WRITE : 0) | EV_PERSIST; |
| f->sockfd = s; | |
| f->action = act; | |
| @@ -371,7 +369,7 @@ static void fifo_cb(int fd, short event, void *arg) | |
| event_base_loopbreak(g->evbase); | |
| } | |
| else | |
| - | new_conn(s, arg); /* if we read a URL, go get it! */ |
| + | new_conn(s, arg); /* if we read a URL, go get it! */ |
| } | |
| else | |
| break; | |
| @@ -41,50 +41,6 @@ struct curl_context { | |
| curl_socket_t sockfd; | |
| }; | |
| - | static void curl_perform(int fd, short event, void *arg); |
| - | |
| - | static struct curl_context *create_curl_context(curl_socket_t sockfd) |
| - | { |
| - | struct curl_context *context; |
| - | |
| - | context = (struct curl_context *)malloc(sizeof(*context)); |
| - | |
| - | context->sockfd = sockfd; |
| - | |
| - | context->event = event_new(base, sockfd, 0, curl_perform, context); |
| - | |
| - | return context; |
| - | } |
| - | |
| - | static void destroy_curl_context(struct curl_context *context) |
| - | { |
| - | event_del(context->event); |
| - | event_free(context->event); |
| - | free(context); |
| - | } |
| - | |
| - | static void add_download(const char *url, int num) |
| - | { |
| - | char filename[50]; |
| - | FILE *file; |
| - | CURL *curl; |
| - | |
| - | snprintf(filename, sizeof(filename), "%d.download", num); |
| - | |
| - | file = fopen(filename, "wb"); |
| - | if(!file) { |
| - | fprintf(stderr, "Error opening %s\n", filename); |
| - | return; |
| - | } |
| - | |
| - | curl = curl_easy_init(); |
| - | curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); |
| - | curl_easy_setopt(curl, CURLOPT_PRIVATE, file); |
| - | curl_easy_setopt(curl, CURLOPT_URL, url); |
| - | curl_multi_add_handle(multi, curl); |
| - | fprintf(stderr, "Added download %s -> %s\n", url, filename); |
| - | } |
| - | |
| static void check_multi_info(void) | |
| { | |
| char *done_url; | |
| @@ -141,6 +97,48 @@ static void curl_perform(int fd, short event, void *arg) | |
| check_multi_info(); | |
| } | |
| + | static struct curl_context *create_curl_context(curl_socket_t sockfd) |
| + | { |
| + | struct curl_context *context; |
| + | |
| + | context = (struct curl_context *)malloc(sizeof(*context)); |
| + | |
| + | context->sockfd = sockfd; |
| + | |
| + | context->event = event_new(base, sockfd, 0, curl_perform, context); |
| + | |
| + | return context; |
| + | } |
| + | |
| + | static void destroy_curl_context(struct curl_context *context) |
| + | { |
| + | event_del(context->event); |
| + | event_free(context->event); |
| + | free(context); |
| + | } |
| + | |
| + | static void add_download(const char *url, int num) |
| + | { |
| + | char filename[50]; |
| + | FILE *file; |
| + | CURL *curl; |
| + | |
| + | snprintf(filename, sizeof(filename), "%d.download", num); |
| + | |
| + | file = fopen(filename, "wb"); |
| + | if(!file) { |
| + | fprintf(stderr, "Error opening %s\n", filename); |
| + | return; |
| + | } |
| + | |
| + | curl = curl_easy_init(); |
| + | curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); |
| + | curl_easy_setopt(curl, CURLOPT_PRIVATE, file); |
| + | curl_easy_setopt(curl, CURLOPT_URL, url); |
| + | curl_multi_add_handle(multi, curl); |
| + | fprintf(stderr, "Added download %s -> %s\n", url, filename); |
| + | } |
| + | |
| static void on_timeout(evutil_socket_t fd, short events, void *arg) | |
| { | |
| int running_handles; | |