Recreate server socket upon receiving SIGUSR1

This commit is contained in:
Marc André Tanner 2014-03-06 17:19:10 +01:00
parent b205eeea9a
commit f7a3290c9c
2 changed files with 45 additions and 25 deletions

View File

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

View File

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