Factor out opts parsing, clean up shutdown.

This commit is contained in:
Ian Gulliver
2016-02-20 23:22:00 -08:00
parent fe5fa29abf
commit 9df778a88a
10 changed files with 151 additions and 100 deletions

View File

@@ -11,5 +11,5 @@ clean:
%.o: %.c *.h
$(CC) -c $(CFLAGS) $< -o $@
adsbus: adsbus.o receive.o send.o incoming.o outgoing.o beast.o json.o raw.o stats.o wakeup.o common.o
$(CC) $(LDFLAGS) -o adsbus adsbus.o receive.o send.o incoming.o outgoing.o beast.o json.o raw.o stats.o wakeup.o common.o $(LIBS)
adsbus: adsbus.o receive.o send.o incoming.o outgoing.o beast.o json.o raw.o stats.o wakeup.o opts.o common.o
$(CC) $(LDFLAGS) -o adsbus adsbus.o receive.o send.o incoming.o outgoing.o beast.o json.o raw.o stats.o wakeup.o opts.o common.o $(LIBS)

View File

@@ -9,13 +9,12 @@
#include "receive.h"
#include "send.h"
#include "incoming.h"
#include "outgoing.h"
#include "beast.h"
#include "json.h"
#include "stats.h"
#include "opts.h"
static void print_usage(const char *name) {
fprintf(stderr,
"\n"
@@ -33,88 +32,6 @@ static void print_usage(const char *name) {
send_print_usage();
}
static bool add_dump(char *arg) {
struct serializer *serializer = send_get_serializer(arg);
if (!serializer) {
fprintf(stderr, "Unknown --dump=FORMAT: %s\n", arg);
return false;
}
send_add(1, serializer);
return true;
}
static bool add_connect_receive(char *arg) {
char *port = strrchr(arg, '/');
if (!port) {
fprintf(stderr, "Invalid --connect-receive=HOST/PORT (missing \"/\"): %s\n", arg);
return false;
}
*(port++) = '\0';
outgoing_new(arg, port, receive_new, NULL);
return true;
}
static bool add_connect_send(char *arg) {
char *host_port = strchr(arg, '=');
if (!host_port) {
fprintf(stderr, "Invalid --connect-send=FORMAT=HOST/PORT (missing \"=\"): %s\n", arg);
return false;
}
*(host_port++) = '\0';
struct serializer *serializer = send_get_serializer(arg);
if (!serializer) {
fprintf(stderr, "Unknown --connect-send=FORMAT=HOST/PORT format: %s\n", arg);
return false;
}
char *port = strrchr(host_port, '/');
if (!port) {
fprintf(stderr, "Invalid --connect-send=FORMAT=HOST/PORT (missing \"/\"): %s\n", host_port);
return false;
}
*(port++) = '\0';
incoming_new(host_port, port, send_add_wrapper, serializer);
return true;
}
static bool add_listen_receive(char *arg){
char *port = strrchr(arg, '/');
if (port) {
*(port++) = '\0';
incoming_new(arg, port, receive_new, NULL);
} else {
incoming_new(NULL, arg, receive_new, NULL);
}
return true;
}
static bool add_listen_send(char *arg) {
char *host_port = strchr(arg, '=');
if (!host_port) {
fprintf(stderr, "Invalid --listen-send=FORMAT=[HOST/]PORT (missing \"=\"): %s\n", arg);
return false;
}
*(host_port++) = '\0';
struct serializer *serializer = send_get_serializer(arg);
if (!serializer) {
fprintf(stderr, "Unknown --listen-send=FORMAT=[HOST/]PORT format: %s\n", arg);
return false;
}
char *port = strrchr(host_port, '/');
if (port) {
*(port++) = '\0';
incoming_new(host_port, port, send_add_wrapper, serializer);
} else {
incoming_new(NULL, host_port, send_add_wrapper, serializer);
}
return true;
}
static bool parse_opts(int argc, char *argv[]) {
static struct option long_options[] = {
{"dump", required_argument, 0, 'd'},
@@ -131,23 +48,23 @@ static bool parse_opts(int argc, char *argv[]) {
bool (*handler)(char *) = NULL;
switch (opt) {
case 'd':
handler = add_dump;
handler = opts_add_dump;
break;
case 'c':
handler = add_connect_receive;
handler = opts_add_connect_receive;
break;
case 's':
handler = add_connect_send;
handler = opts_add_connect_send;
break;
case 'l':
handler = add_listen_receive;
handler = opts_add_listen_receive;
break;
case 'm':
handler = add_listen_send;
handler = opts_add_listen_send;
break;
case 'h':
@@ -158,6 +75,7 @@ static bool parse_opts(int argc, char *argv[]) {
if (handler) {
if (!handler(optarg)) {
fprintf(stderr, "Invalid flag value: %s\n", optarg);
print_usage(argv[0]);
return false;
}
@@ -190,5 +108,7 @@ int main(int argc, char *argv[]) {
}
peer_loop();
send_cleanup();
return EXIT_SUCCESS;
}

View File

@@ -1,16 +1,24 @@
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <uuid/uuid.h>
#include "common.h"
int epoll_fd;
static int epoll_fd;
static bool peer_canceled = false;
static void peer_cancel(int signal) {
peer_canceled = true;
}
void peer_init() {
signal(SIGINT, peer_cancel);
epoll_fd = epoll_create1(0);
assert(epoll_fd >= 0);
}
@@ -30,11 +38,14 @@ void peer_epoll_del(struct peer *peer) {
}
void peer_loop() {
while (1) {
while (!peer_canceled) {
#define MAX_EVENTS 10
struct epoll_event events[MAX_EVENTS];
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
assert(nfds >= 0);
if (nfds < 0) {
perror("epoll_wait");
break;
}
for (int n = 0; n < nfds; n++) {
struct peer *peer = events[n].data.ptr;

View File

@@ -13,7 +13,6 @@ struct peer {
int fd;
peer_event_handler event_handler;
};
extern int epoll_fd;
void peer_init();
void peer_epoll_add(struct peer *, uint32_t);
void peer_epoll_del(struct peer *);

View File

@@ -52,8 +52,8 @@ void incoming_new(const char *node, const char *service, incoming_connection_han
struct incoming *incoming = malloc(sizeof(*incoming));
incoming->peer.event_handler = incoming_handler;
uuid_gen(incoming->id);
incoming->node = node;
incoming->service = service;
incoming->node = strdup(node);
incoming->service = strdup(service);
incoming->handler = handler;
incoming->passthrough = passthrough;
@@ -69,6 +69,7 @@ void incoming_new(const char *node, const char *service, incoming_connection_han
int gai_err = getaddrinfo(incoming->node, incoming->service, &hints, &addrs);
if (gai_err) {
fprintf(stderr, "I %s: Failed to resolve %s/%s: %s\n", incoming->id, incoming->node, incoming->service, gai_strerror(gai_err));
// TODO: add incoming_del, free strdup values
free(incoming);
return;
}
@@ -99,6 +100,7 @@ void incoming_new(const char *node, const char *service, incoming_connection_han
if (addr == NULL) {
fprintf(stderr, "I %s: Failed to bind any addresses for %s/%s...\n", incoming->id, incoming->node, incoming->service);
// TODO: use incoming_del
free(incoming);
return;
}

97
adsbus/opts.c Normal file
View File

@@ -0,0 +1,97 @@
#include <stdlib.h>
#include <string.h>
#include "incoming.h"
#include "outgoing.h"
#include "receive.h"
#include "send.h"
#include "opts.h"
static char *opts_split(char **arg, char delim) {
char *split = strchr(*arg, delim);
if (!split) {
return NULL;
}
char *ret = strndup(*arg, split - *arg);
*arg = split + 1;
return ret;
}
bool opts_add_dump(char *arg) {
struct serializer *serializer = send_get_serializer(arg);
if (!serializer) {
return false;
}
send_add(1, serializer);
return true;
}
bool opts_add_connect_receive(char *arg) {
char *host = opts_split(&arg, '/');
if (!host) {
return false;
}
outgoing_new(host, arg, receive_new, NULL);
free(host);
return true;
}
bool opts_add_connect_send(char *arg) {
char *format = opts_split(&arg, '=');
if (!format) {
return false;
}
struct serializer *serializer = send_get_serializer(format);
if (!serializer) {
free(format);
return false;
}
char *host = opts_split(&arg, '/');
if (!host) {
free(format);
return false;
}
incoming_new(host, arg, send_add_wrapper, serializer);
free(format);
free(host);
return true;
}
bool opts_add_listen_receive(char *arg) {
char *host = opts_split(&arg, '/');
if (host) {
incoming_new(host, arg, receive_new, NULL);
free(host);
} else {
incoming_new(NULL, arg, receive_new, NULL);
}
return true;
}
bool opts_add_listen_send(char *arg) {
char *format = opts_split(&arg, '=');
if (!format) {
return false;
}
struct serializer *serializer = send_get_serializer(format);
if (!serializer) {
free(format);
return false;
}
char *host = opts_split(&arg, '/');
if (host) {
incoming_new(host, arg, send_add_wrapper, serializer);
free(host);
} else {
incoming_new(NULL, arg, send_add_wrapper, serializer);
}
return true;
}

9
adsbus/opts.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <stdbool.h>
bool opts_add_dump(char *);
bool opts_add_connect_receive(char *);
bool opts_add_connect_send(char *);
bool opts_add_listen_receive(char *);
bool opts_add_listen_send(char *);

View File

@@ -113,8 +113,8 @@ static void outgoing_resolve(struct outgoing *outgoing) {
void outgoing_new(const char *node, const char *service, outgoing_connection_handler handler, void *passthrough) {
struct outgoing *outgoing = malloc(sizeof(*outgoing));
uuid_gen(outgoing->id);
outgoing->node = node;
outgoing->service = service;
outgoing->node = strdup(node);
outgoing->service = strdup(service);
outgoing->handler = handler;
outgoing->passthrough = passthrough;
outgoing_resolve(outgoing);

View File

@@ -82,6 +82,18 @@ void send_init() {
signal(SIGPIPE, SIG_IGN);
}
void send_cleanup() {
for (int i = 0; i < NUM_SERIALIZERS; i++) {
struct serializer *serializer = &serializers[i];
struct send *send = serializer->send_head;
while (send) {
struct send *next = send->next;
free(send);
send = next;
}
}
}
struct serializer *send_get_serializer(char *name) {
for (int i = 0; i < NUM_SERIALIZERS; i++) {
if (strcasecmp(serializers[i].name, name) == 0) {

View File

@@ -3,6 +3,7 @@
#include "common.h"
void send_init();
void send_cleanup();
struct serializer *send_get_serializer(char *);
void send_add(int, struct serializer *);
void send_add_wrapper(int, void *);