abduco

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | LICENSE

commit f7a3290c9cc0c6fa8c2926a6f222e2354d83f45c
parent b205eeea9a183d68cdcb874dfaea1e0f99249ef0
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Thu,  6 Mar 2014 17:19:10 +0100

Recreate server socket upon receiving SIGUSR1

Diffstat:
abduco.c | 39+++++++++++++++------------------------
server.c | 31++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/abduco.c b/abduco.c @@ -119,6 +119,7 @@ typedef struct { pid_t pid; volatile sig_atomic_t running; const char *name; + const char *session_name; } Server; static Server server = { .running = true, .exit_status = -1 }; @@ -210,24 +211,15 @@ static int create_socket(const char *name) { static bool create_session(const char *name, char * const argv[]) { int pipefds[2]; - if (pipe(pipefds) == -1) - return false; - if ((server.socket = create_socket(name)) == -1) - return false; - socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1; - mode_t mode = S_IRUSR|S_IWUSR; - fchmod(server.socket, mode); - if (bind(server.socket, (struct sockaddr*)&sockaddr, socklen) == -1) - return false; - if (listen(server.socket, 5) == -1) - goto error; - if (fchmod(server.socket, mode) == -1 && chmod(sockaddr.sun_path, mode) == -1) - goto error; - pid_t pid; char errormsg[255]; struct sigaction sa; + if (pipe(pipefds) == -1) + return false; + if ((server.socket = server_create_socket(name)) == -1) + return false; + switch ((pid = fork())) { case 0: /* child process */ setsid(); @@ -256,6 +248,8 @@ static bool create_session(const char *name, char * const argv[]) { sa.sa_handler = server_sigterm_handler; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); + sa.sa_handler = server_sigusr1_handler; + sigaction(SIGUSR1, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); sigaction(SIGHUP, &sa, NULL); @@ -291,9 +285,6 @@ static bool create_session(const char *name, char * const argv[]) { close(pipefds[0]); } return true; -error: - unlink(sockaddr.sun_path); - return false; } static bool attach_session(const char *name) { @@ -376,21 +367,21 @@ static int list_session() { } int main(int argc, char *argv[]) { - char *session = NULL, **cmd = NULL, action = '\0'; + char **cmd = NULL, action = '\0'; server.name = basename(argv[0]); if (argc == 1) exit(list_session()); for (int arg = 1; arg < argc; arg++) { if (argv[arg][0] != '-') { - if (!session) { - session = argv[arg]; + if (!server.session_name) { + server.session_name = argv[arg]; continue; } else if (!cmd) { cmd = &argv[arg]; break; } } - if (session) + if (server.session_name) usage(); switch (argv[arg][1]) { case 'a': @@ -415,7 +406,7 @@ int main(int argc, char *argv[]) { } } - if (!action || !session || (action != 'a' && !cmd)) + if (!action || !server.session_name || (action != 'a' && !cmd)) usage(); if (tcgetattr(STDIN_FILENO, &orig_term) != -1) { @@ -427,13 +418,13 @@ int main(int argc, char *argv[]) { redo: case 'n': case 'c': - if (!create_session(session, cmd)) + if (!create_session(server.session_name, cmd)) die("create-session"); if (action == 'n') break; case 'a': case 'A': - if (!attach_session(session)) { + if (!attach_session(server.session_name)) { if (action == 'A') { action = 'c'; goto redo; diff --git a/server.c b/server.c @@ -18,6 +18,26 @@ static void client_free(Client *c) { free(c); } +static int server_create_socket(const char *name) { + int socket = create_socket(name); + if (socket == -1) + return -1; + socklen_t socklen = offsetof(struct sockaddr_un, sun_path) + strlen(sockaddr.sun_path) + 1; + mode_t mode = S_IRUSR|S_IWUSR; + fchmod(socket, mode); + if (bind(socket, (struct sockaddr*)&sockaddr, socklen) == -1) + return -1; + if (fchmod(socket, mode) == -1 && chmod(sockaddr.sun_path, mode) == -1) + goto error; + if (listen(socket, 5) == -1) + goto error; + debug("old: %d new: %d\n", server.socket, socket); + return socket; +error: + unlink(sockaddr.sun_path); + return -1; +} + static int server_set_socket_non_blocking(int sock) { int flags; if ((flags = fcntl(sock, F_GETFL, 0)) == -1) @@ -154,6 +174,15 @@ static void server_sigterm_handler(int sig) { exit(EXIT_FAILURE); /* invoke atexit handler */ } +static void server_sigusr1_handler(int sig) { + int socket = server_create_socket(server.session_name); + if (socket != -1) { + if (server.socket) + close(server.socket); + server.socket = socket; + } +} + static void server_atexit_handler() { unlink(sockaddr.sun_path); } @@ -194,6 +223,7 @@ static void server_mainloop() { int fdmax = new_fdmax; fd_set readfds = new_readfds; fd_set writefds = new_writefds; + FD_SET_MAX(server.socket, &readfds, fdmax); if (!server.running && server.exit_status != -1 && server.clients) { /* application terminated */ Packet pkt = { .type = MSG_EXIT, .len = sizeof(int), .u.i = server.exit_status }; @@ -214,7 +244,6 @@ static void server_mainloop() { } FD_ZERO(&new_readfds); - FD_SET(server.socket, &new_readfds); FD_ZERO(&new_writefds); new_fdmax = server.socket;