forked from github/abduco
Recreate server socket upon receiving SIGUSR1
This commit is contained in:
parent
b205eeea9a
commit
f7a3290c9c
39
abduco.c
39
abduco.c
|
|
@ -119,6 +119,7 @@ typedef struct {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
volatile sig_atomic_t running;
|
volatile sig_atomic_t running;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
const char *session_name;
|
||||||
} Server;
|
} Server;
|
||||||
|
|
||||||
static Server server = { .running = true, .exit_status = -1 };
|
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[]) {
|
static bool create_session(const char *name, char * const argv[]) {
|
||||||
int pipefds[2];
|
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;
|
pid_t pid;
|
||||||
char errormsg[255];
|
char errormsg[255];
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
|
if (pipe(pipefds) == -1)
|
||||||
|
return false;
|
||||||
|
if ((server.socket = server_create_socket(name)) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
switch ((pid = fork())) {
|
switch ((pid = fork())) {
|
||||||
case 0: /* child process */
|
case 0: /* child process */
|
||||||
setsid();
|
setsid();
|
||||||
|
|
@ -256,6 +248,8 @@ static bool create_session(const char *name, char * const argv[]) {
|
||||||
sa.sa_handler = server_sigterm_handler;
|
sa.sa_handler = server_sigterm_handler;
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
sigaction(SIGTERM, &sa, NULL);
|
||||||
sigaction(SIGINT, &sa, NULL);
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
sa.sa_handler = server_sigusr1_handler;
|
||||||
|
sigaction(SIGUSR1, &sa, NULL);
|
||||||
sa.sa_handler = SIG_IGN;
|
sa.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &sa, NULL);
|
sigaction(SIGPIPE, &sa, NULL);
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
sigaction(SIGHUP, &sa, NULL);
|
||||||
|
|
@ -291,9 +285,6 @@ static bool create_session(const char *name, char * const argv[]) {
|
||||||
close(pipefds[0]);
|
close(pipefds[0]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
error:
|
|
||||||
unlink(sockaddr.sun_path);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool attach_session(const char *name) {
|
static bool attach_session(const char *name) {
|
||||||
|
|
@ -376,21 +367,21 @@ static int list_session() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
char *session = NULL, **cmd = NULL, action = '\0';
|
char **cmd = NULL, action = '\0';
|
||||||
server.name = basename(argv[0]);
|
server.name = basename(argv[0]);
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
exit(list_session());
|
exit(list_session());
|
||||||
for (int arg = 1; arg < argc; arg++) {
|
for (int arg = 1; arg < argc; arg++) {
|
||||||
if (argv[arg][0] != '-') {
|
if (argv[arg][0] != '-') {
|
||||||
if (!session) {
|
if (!server.session_name) {
|
||||||
session = argv[arg];
|
server.session_name = argv[arg];
|
||||||
continue;
|
continue;
|
||||||
} else if (!cmd) {
|
} else if (!cmd) {
|
||||||
cmd = &argv[arg];
|
cmd = &argv[arg];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (session)
|
if (server.session_name)
|
||||||
usage();
|
usage();
|
||||||
switch (argv[arg][1]) {
|
switch (argv[arg][1]) {
|
||||||
case 'a':
|
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();
|
usage();
|
||||||
|
|
||||||
if (tcgetattr(STDIN_FILENO, &orig_term) != -1) {
|
if (tcgetattr(STDIN_FILENO, &orig_term) != -1) {
|
||||||
|
|
@ -427,13 +418,13 @@ int main(int argc, char *argv[]) {
|
||||||
redo:
|
redo:
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'c':
|
case 'c':
|
||||||
if (!create_session(session, cmd))
|
if (!create_session(server.session_name, cmd))
|
||||||
die("create-session");
|
die("create-session");
|
||||||
if (action == 'n')
|
if (action == 'n')
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A':
|
case 'A':
|
||||||
if (!attach_session(session)) {
|
if (!attach_session(server.session_name)) {
|
||||||
if (action == 'A') {
|
if (action == 'A') {
|
||||||
action = 'c';
|
action = 'c';
|
||||||
goto redo;
|
goto redo;
|
||||||
|
|
|
||||||
31
server.c
31
server.c
|
|
@ -18,6 +18,26 @@ static void client_free(Client *c) {
|
||||||
free(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) {
|
static int server_set_socket_non_blocking(int sock) {
|
||||||
int flags;
|
int flags;
|
||||||
if ((flags = fcntl(sock, F_GETFL, 0)) == -1)
|
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 */
|
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() {
|
static void server_atexit_handler() {
|
||||||
unlink(sockaddr.sun_path);
|
unlink(sockaddr.sun_path);
|
||||||
}
|
}
|
||||||
|
|
@ -194,6 +223,7 @@ static void server_mainloop() {
|
||||||
int fdmax = new_fdmax;
|
int fdmax = new_fdmax;
|
||||||
fd_set readfds = new_readfds;
|
fd_set readfds = new_readfds;
|
||||||
fd_set writefds = new_writefds;
|
fd_set writefds = new_writefds;
|
||||||
|
FD_SET_MAX(server.socket, &readfds, fdmax);
|
||||||
|
|
||||||
if (!server.running && server.exit_status != -1 && server.clients) { /* application terminated */
|
if (!server.running && server.exit_status != -1 && server.clients) { /* application terminated */
|
||||||
Packet pkt = { .type = MSG_EXIT, .len = sizeof(int), .u.i = server.exit_status };
|
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_ZERO(&new_readfds);
|
||||||
FD_SET(server.socket, &new_readfds);
|
|
||||||
FD_ZERO(&new_writefds);
|
FD_ZERO(&new_writefds);
|
||||||
new_fdmax = server.socket;
|
new_fdmax = server.socket;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue