# HG changeset patch # User František Kučera # Date 1479670748 -3600 # Node ID ba40af6cf81565191238d548a07cb110641809e3 # Parent 988b56d4a7b8c6f04337c84c260787139219ff53 libevent: formátování výstupu, sjednocení, angličtina diff -r 988b56d4a7b8 -r ba40af6cf815 c++/domain-socket-bridge/domain-socket-bridge.c --- a/c++/domain-socket-bridge/domain-socket-bridge.c Sun Nov 20 18:22:56 2016 +0100 +++ b/c++/domain-socket-bridge/domain-socket-bridge.c Sun Nov 20 20:39:08 2016 +0100 @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include @@ -13,18 +15,23 @@ #include #include +using namespace std; + static const char MESSAGE[] = "Hello, World!\n"; static const char PATH[] = "./roura"; +static const string COMMAND_EXIT("exit\n"); + static void listener_cb(evutil_socket_t, short, void *); static void conn_read_cb(struct bufferevent *, void *); static void conn_write_cb(struct bufferevent *, void *); static void conn_event_cb(struct bufferevent *, short, void *); static void signal_cb(evutil_socket_t, short, void *); -static void print_socket_info(int); +static void print_socket_info(int, int); int main(int argc, char **argv) { + printf("%4s %8s\n", "*", "STARTED"); struct event_base *base; evutil_socket_t listener; struct event *listener_event; @@ -36,7 +43,7 @@ base = event_base_new(); if (!base) { - fprintf(stderr, "Could not initialize libevent!\n"); + printf("%4s %8s %s\n", "*", "ERROR", "unable to initialize libevent"); return 1; } @@ -48,22 +55,22 @@ evutil_make_socket_nonblocking(listener); if (bind(listener, (struct sockaddr*) &sun, sizeof (sun)) < 0) { - fprintf(stderr, "Could not create domain socket: %s!\n", PATH); + printf("%4s %8s %s: %s\n", "*", "ERROR", "unable to create domain socket:", PATH); return 1; } if (listen(listener, 16) < 0) { - fprintf(stderr, "Could not listen\n"); + printf("%4s %8s %s\n", "*", "ERROR", "unable to listen"); return 1; } // identifikátor serverového soketu (v současnosti číslo FD) - printf("Nasloucháme: sun_path = %s → socketId = %d\n", sun.sun_path, listener); + printf("%4s %8s listening at: sun_path = %s → socketId = %d\n", "*", "SOCKET", sun.sun_path, listener); listener_event = event_new(base, listener, EV_READ | EV_PERSIST, listener_cb, (void*) base); if (!listener_event) { - fprintf(stderr, "Could not do event_new\n"); + printf("%4s %8s %s\n", "*", "ERROR", "unable to do event_new()"); return 1; } @@ -72,7 +79,7 @@ signal_event = evsignal_new(base, SIGINT, signal_cb, (void *) base); if (!signal_event || event_add(signal_event, NULL) < 0) { - fprintf(stderr, "Could not create/add a signal event!\n"); + printf("%4s %8s %s\n", "*", "ERROR", "unable to create/add a signal event"); return 1; } @@ -86,7 +93,7 @@ // TODO: co když soket někdo přesune a místo něj dá jiný soubor? unlink(PATH); - printf("done\n"); + printf("%4s %8s\n", "*", "FINISHED"); return 0; } @@ -97,42 +104,45 @@ struct sockaddr_storage ss; socklen_t slen = sizeof (ss); int fd = accept(listener, (struct sockaddr*) &ss, &slen); + + // identifikátor navázaného spojení (v současnosti číslo FD) + int * connectionId = (int*) malloc(sizeof (fd)); + *connectionId = fd; + if (fd < 0) { - fprintf(stderr, "Unable to accept(): %d", fd); + printf("%4d %8s %s\n", *connectionId, "ERROR", "unable to accept()"); return; } else if (fd > FD_SETSIZE) { // FD_SETSIZE = 1024 -- Proč? Co když bude spojení víc? - fprintf(stderr, "fd (%d) > FD_SETSIZE (%d)", fd, FD_SETSIZE); + printf("%4d %8s fd (%d) > FD_SETSIZE (%d)\n", *connectionId, "ERROR", fd, FD_SETSIZE); close(fd); return; } evutil_make_socket_nonblocking(fd); - print_socket_info(fd); bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); if (!bev) { - fprintf(stderr, "Error constructing bufferevent!"); + printf("%4d %8s %s\n", *connectionId, "ERROR", "constructing bufferevent"); event_base_loopbreak(base); return; } - // identifikátor navázaného spojení (v současnosti číslo FD) - int * connectionId = (int*) malloc(sizeof (fd)); - *connectionId = fd; + bufferevent_setcb(bev, conn_read_cb, conn_write_cb, conn_event_cb, (void*) connectionId); bufferevent_enable(bev, EV_READ | EV_WRITE); - printf("někdo se k nám připojil! socketId = %d → connectionId = %d / bev = %p\n", listener, *connectionId, bev); + printf("%4d %8s somebody has connected: socketId = %d → connectionId = %d\n", *connectionId, "CONN", listener, *connectionId); + print_socket_info(*connectionId, fd); bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); } static void conn_read_cb(struct bufferevent *bev, void *user_data) { - printf("conn_read_cb: connectionId = %d\n", *((int*) user_data)); + int connectionId = *((int*) user_data); /* This callback is invoked when there is data to read on bev. */ struct evbuffer *input = bufferevent_get_input(bev); @@ -142,11 +152,15 @@ size_t len = evbuffer_get_length(input); char *data = (char*) malloc(len); evbuffer_copyout(input, data, len); - printf("we got some data: %s\n", data); - if (memcmp(data, "exit\n", len) == 0) { + + string dataFormated(data); + dataFormated = regex_replace(dataFormated, regex("\\n"), "\\n"); + printf("%4d %8s '%s'\n", connectionId, "IN", dataFormated.c_str()); + + if (COMMAND_EXIT.compare(data) == 0) { struct timeval delay = {2, 123}; - printf("Klient říká, že máme končit; ukončuji program během %ld sekund a %ld mikrosekund.\n", delay.tv_sec, delay.tv_usec); + printf("%4d %8s client asks us to terminate; finishing in %ld sesonds and %ld microseconds\n", connectionId, "EXIT", delay.tv_sec, delay.tv_usec); event_base_loopexit(base, &delay); } @@ -157,28 +171,36 @@ } static void conn_write_cb(struct bufferevent *bev, void *user_data) { - printf("conn_write_cb: connectionId = %d\n", *((int*) user_data)); + int connectionId = *((int*) user_data); struct evbuffer *output = bufferevent_get_output(bev); if (evbuffer_get_length(output) == 0) { - printf("flushed answer / %p\n", bev); + printf("%4d %8s\n", connectionId, "FLUSH"); /* nebudeme ukončovat spojení bufferevent_free(bev); */ + } else { + // FIXME: sem to nikdy nepřijde + size_t len = evbuffer_get_length(output); + char *data = (char*) malloc(len); + evbuffer_copyout(output, data, len); + printf("%4d %8s '%s'\n", connectionId, "OUT", data); + free(data); } } static void conn_event_cb(struct bufferevent *bev, short events, void *user_data) { int connectionId = *((int*) user_data); - printf("conn_event_cb: connectionId = %d\n", connectionId); if (events & BEV_EVENT_EOF) { - printf("Connection closed: connectionId = %d\n", connectionId); + printf("%4d %8s\n", connectionId, "CLOSE"); } else if (events & BEV_EVENT_ERROR) { - printf("Got an error on the connectionId = %d: %s\n", connectionId, strerror(errno)); + printf("%4d %8s %s\n", connectionId, "ERROR", strerror(errno)); + } else { + printf("%4d %8s\n", connectionId, "OTHER"); + // None of the other events can happen here, since we haven't enabled timeouts } - // None of the other events can happen here, since we haven't enabled timeouts bufferevent_free(bev); free(user_data); } @@ -187,16 +209,16 @@ struct event_base *base = (event_base *) user_data; struct timeval delay = {2, 123}; - printf("Zachycen SIGINT (Ctrl+C); ukončuji program během %ld sekund a %ld mikrosekund.\n", delay.tv_sec, delay.tv_usec); + printf("\n%4s %8s got SIGINT (Ctrl+C); finishing in %ld sesonds and %ld microseconds\n", "*", "SIGNAL", delay.tv_sec, delay.tv_usec); event_base_loopexit(base, &delay); } -static void print_socket_info(int fd) { +static void print_socket_info(int connectionId, int fd) { struct ucred cr; unsigned int cl = sizeof (cr); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0) { - printf("připojený klient: pid=%d, uid=%d, gid=%d\n", cr.pid, cr.uid, cr.gid); + printf("%4d %8s client identification: pid=%d, uid=%d, gid=%d\n", connectionId, "CONN", cr.pid, cr.uid, cr.gid); } } \ No newline at end of file