Make restart IPC command send a reply once restart completed (!) (#3743)

This is achieved by retaining the IPC connection which is sending the restart
command across the restart.

This is the cleaner fix for https://github.com/i3/go-i3/issues/3

fixes #3565
This commit is contained in:
Michael Stapelberg
2019-07-21 14:52:12 +02:00
committed by GitHub
parent 1eabe1b2b1
commit e4ecc6e4a1
10 changed files with 126 additions and 24 deletions

View File

@ -12,6 +12,8 @@
#include <stdint.h>
#include <float.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include "shmlog.h"
@ -1590,15 +1592,27 @@ void cmd_reload(I3_CMD) {
*/
void cmd_restart(I3_CMD) {
LOG("restarting i3\n");
ipc_shutdown(SHUTDOWN_REASON_RESTART);
int exempt_fd = -1;
if (cmd_output->client != NULL) {
exempt_fd = cmd_output->client->fd;
LOG("Carrying file descriptor %d across restart\n", exempt_fd);
int flags;
if ((flags = fcntl(exempt_fd, F_GETFD)) < 0 ||
fcntl(exempt_fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) {
ELOG("Could not disable FD_CLOEXEC on fd %d\n", exempt_fd);
}
char *fdstr = NULL;
sasprintf(&fdstr, "%d", exempt_fd);
setenv("_I3_RESTART_FD", fdstr, 1);
}
ipc_shutdown(SHUTDOWN_REASON_RESTART, exempt_fd);
unlink(config.ipc_socket_path);
/* We need to call this manually since atexit handlers dont get called
* when exec()ing */
purge_zerobyte_logfile();
i3_restart(false);
// XXX: default reply for now, make this a better reply
ysuccess(true);
/* unreached */
assert(false);
}
/*