examples: omit forward declarations, apply misc fixes

- reorder functions to not need forward declarations.
- sync `ephiperfifo.c` and `evhiperfifo.c`.
- drop redundant casts for `calloc()` return value.
- ephiperfifo: silence unused variable warning.
- fix indent and apply clang-format more.

Closes #20296
This commit is contained in:
Viktor Szakats 2026-01-13 18:17:42 +01:00
parent df246eeb8f
commit 8680a07589
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
6 changed files with 158 additions and 161 deletions

View File

@ -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;

View File

@ -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,7 +140,61 @@ static void mcode_or_die(const char *where, CURLMcode code)
}
}
static void timer_cb(struct GlobalInfo *g, int revents);
/* Check for completed transfers, and remove their easy handles */
static void check_multi_info(struct GlobalInfo *g)
{
char *eff_url;
CURLMsg *msg;
int msgs_left;
struct ConnInfo *conn;
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if(msg->msg == CURLMSG_DONE) {
CURL *curl = msg->easy_handle;
CURLcode result = msg->data.result;
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &conn);
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &eff_url);
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, result, conn->error);
curl_multi_remove_handle(g->multi, curl);
free(conn->url);
curl_easy_cleanup(curl);
free(conn);
}
}
}
/* Called by main loop when our timeout expires */
static void timer_cb(struct GlobalInfo *g, int revents)
{
CURLMcode mresult;
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
* readable. It is possible that there are multiple events stored in the
* epoll buffer (i.e. the timer may have fired multiple times). The event
* count is cleared after the first call so future events in the epoll
* buffer fails to read from the timer. */
if(errno == EAGAIN) {
fprintf(MSG_OUT, "EAGAIN on tfd %d\n", g->tfd);
return;
}
}
if(err != sizeof(uint64_t)) {
fprintf(stderr, "read(tfd) == %ld", err);
perror("read(tfd)");
}
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,
@ -149,6 +203,8 @@ 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) {
@ -174,30 +230,6 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g)
return 0;
}
/* Check for completed transfers, and remove their easy handles */
static void check_multi_info(struct GlobalInfo *g)
{
char *eff_url;
CURLMsg *msg;
int msgs_left;
struct ConnInfo *conn;
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if(msg->msg == CURLMSG_DONE) {
CURL *curl = msg->easy_handle;
CURLcode result = msg->data.result;
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &conn);
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &eff_url);
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, result, conn->error);
curl_multi_remove_handle(g->multi, curl);
free(conn->url);
curl_easy_cleanup(curl);
free(conn);
}
}
}
/* Called by libevent when we get action on a multi socket filedescriptor */
static void event_cb(struct GlobalInfo *g, int fd, int revents)
{
@ -205,7 +237,7 @@ static void event_cb(struct GlobalInfo *g, int fd, int revents)
struct itimerspec its;
int action = ((revents & EPOLLIN) ? CURL_CSELECT_IN : 0) |
((revents & EPOLLOUT) ? CURL_CSELECT_OUT : 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);
@ -218,36 +250,6 @@ static void event_cb(struct GlobalInfo *g, int fd, int revents)
}
}
/* Called by main loop when our timeout expires */
static void timer_cb(struct GlobalInfo *g, int revents)
{
CURLMcode mresult;
uint64_t count = 0;
ssize_t err = 0;
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
* readable. It is possible that there are multiple events stored in the
* epoll buffer (i.e. the timer may have fired multiple times). The event
* count is cleared after the first call so future events in the epoll
* buffer fails to read from the timer. */
if(errno == EAGAIN) {
fprintf(MSG_OUT, "EAGAIN on tfd %d\n", g->tfd);
return;
}
}
if(err != sizeof(uint64_t)) {
fprintf(stderr, "read(tfd) == %ld", err);
perror("read(tfd)");
}
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);
}
/* 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;

View File

@ -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,18 +168,49 @@ static void check_multi_info(struct GlobalInfo *g)
}
}
/* Called by libevent when our timeout expires */
static void timer_cb(EV_P_ struct ev_timer *w, int revents)
{
CURLMcode mresult;
struct GlobalInfo *g;
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);
check_multi_info(g);
}
/* 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 we get action on a multi socket */
static void event_cb(EV_P_ struct ev_io *w, int revents)
{
struct GlobalInfo *g;
CURLMcode mresult;
int action;
struct GlobalInfo *g;
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;
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,
&g->still_running);
mcode_or_die("event_cb: curl_multi_socket_action", mresult);
@ -207,22 +221,6 @@ 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;
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);
check_multi_info(g);
}
/* Clean up the SockInfo structure */
static void remsock(struct SockInfo *f, struct GlobalInfo *g)
{
@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;