fix bug where attaching to dead session won't give underlying exit code

If dvtm dies, and you run `:|abduco -a session`, abduco will often exit
without giving you the exit code, and without removing the socket from
~/.abduco.

We resolve this by first sending the client either an EXIT or an empty
CONTENT packet.

Only after the client recieves it, we set the socket to non-blocking.

Fixes: https://github.com/martanne/abduco/issues/44
This commit is contained in:
Jeremy Bobbin 2021-01-30 01:02:27 -08:00
parent 8c32909a15
commit 972ca8ab94
3 changed files with 35 additions and 13 deletions

View File

@ -518,8 +518,6 @@ static bool attach_session(const char *name, const bool terminate) {
close(server.socket); close(server.socket);
if ((server.socket = session_connect(name)) == -1) if ((server.socket = session_connect(name)) == -1)
return false; return false;
if (server_set_socket_non_blocking(server.socket) == -1)
return false;
struct sigaction sa; struct sigaction sa;
sa.sa_flags = 0; sa.sa_flags = 0;
@ -529,9 +527,25 @@ static bool attach_session(const char *name, const bool terminate) {
sa.sa_handler = SIG_IGN; sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL); sigaction(SIGPIPE, &sa, NULL);
client_setup_terminal(); Packet pkt = {
int status = client_mainloop(); .type = MSG_ATTACH,
client_restore_terminal(); .u.i = client.flags,
.len = sizeof(pkt.u.i),
};
client_send_packet(&pkt);
int status;
if (client_recv_packet(&pkt) && pkt.type == MSG_PID) {
if (server_set_socket_non_blocking(server.socket) == -1)
return false;
client_setup_terminal();
status = client_mainloop();
client_restore_terminal();
} else if (pkt.type == MSG_EXIT) {
status = pkt.u.i;
client_send_packet(&pkt);
close(server.socket);
}
if (status == -1) { if (status == -1) {
info("detached"); info("detached");
} else if (status == -EIO) { } else if (status == -EIO) {

View File

@ -63,13 +63,6 @@ static int client_mainloop(void) {
sigprocmask(SIG_BLOCK, &blockset, NULL); sigprocmask(SIG_BLOCK, &blockset, NULL);
client.need_resize = true; client.need_resize = true;
Packet pkt = {
.type = MSG_ATTACH,
.u.i = client.flags,
.len = sizeof(pkt.u.i),
};
client_send_packet(&pkt);
while (server.running) { while (server.running) {
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);

View File

@ -222,11 +222,26 @@ static void server_mainloop(void) {
case MSG_CONTENT: case MSG_CONTENT:
server_write_pty(&client_packet); server_write_pty(&client_packet);
break; break;
case MSG_ATTACH: case MSG_ATTACH: {
Packet pkt;
if (!server.running && server.exit_status != -1) {
pkt = (Packet) {
.type = MSG_EXIT,
.u.i = server.exit_status,
.len = sizeof(pkt.u.i),
};
} else {
pkt = (Packet) {
.type = MSG_CONTENT,
.len = 0,
};
}
server_send_packet(c, &pkt);
c->flags = client_packet.u.i; c->flags = client_packet.u.i;
if (c->flags & CLIENT_LOWPRIORITY) if (c->flags & CLIENT_LOWPRIORITY)
server_sink_client(); server_sink_client();
break; break;
}
case MSG_RESIZE: case MSG_RESIZE:
c->state = STATE_ATTACHED; c->state = STATE_ATTACHED;
if (!(c->flags & CLIENT_READONLY) && c == server.clients) { if (!(c->flags & CLIENT_READONLY) && c == server.clients) {