Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use self-pipe instead of signal-blocking for SIGCHLD/SIGWINCH #69

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 60 additions & 10 deletions dvtm.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ typedef struct {
int history;
int w;
int h;
volatile sig_atomic_t need_resize;
bool need_resize;
} Screen;

typedef struct {
Expand Down Expand Up @@ -248,6 +248,10 @@ static const char *shell;
static Register copyreg;
static volatile sig_atomic_t running = true;
static bool runinall = false;
static int sigwinch_pipe[] = {-1, -1};
static int sigchld_pipe[] = {-1, -1};

enum {PIPE_RD, PIPE_WR};

static void
eprint(const char *errstr, ...) {
Expand Down Expand Up @@ -698,6 +702,11 @@ get_client_by_coord(unsigned int x, unsigned int y) {

static void
sigchld_handler(int sig) {
write(sigchld_pipe[PIPE_WR], "\0", 1);
}

static void
handle_sigchld() {
int errsv = errno;
int status;
pid_t pid;
Expand Down Expand Up @@ -731,6 +740,11 @@ sigchld_handler(int sig) {

static void
sigwinch_handler(int sig) {
write(sigwinch_pipe[PIPE_WR], "\0", 1);
}

static void
handle_sigwinch() {
screen.need_resize = true;
}

Expand Down Expand Up @@ -939,6 +953,14 @@ getshell(void) {
return "/bin/sh";
}

static bool
set_blocking(int fd, bool blocking) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) return false;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return !fcntl(fd, F_SETFL, flags);
}

static void
setup(void) {
shell = getshell();
Expand All @@ -962,6 +984,23 @@ setup(void) {
colors[i].pair = vt_color_reserve(colors[i].fg, colors[i].bg);
}
resize_screen();

int *pipes[] = {&sigwinch_pipe[0], &sigchld_pipe[0]};
for (int i = 0; i < 2; ++i) {
int r = pipe(pipes[i]);
if (r < 0) {
perror("pipe()");
exit(EXIT_FAILURE);
}

for (int j = 0; j < 2; ++j) {
if (!set_blocking(pipes[i][j], false)) {
perror("fcntl()");
exit(EXIT_FAILURE);
}
}
}

struct sigaction sa;
memset(&sa, 0, sizeof sa);
sa.sa_flags = 0;
Expand Down Expand Up @@ -1815,20 +1854,13 @@ main(int argc, char *argv[]) {
KeyCombo keys;
unsigned int key_index = 0;
memset(keys, 0, sizeof(keys));
sigset_t emptyset, blockset;

setenv("DVTM", VERSION, 1);
if (!parse_args(argc, argv)) {
setup();
startup(NULL);
}

sigemptyset(&emptyset);
sigemptyset(&blockset);
sigaddset(&blockset, SIGWINCH);
sigaddset(&blockset, SIGCHLD);
sigprocmask(SIG_BLOCK, &blockset, NULL);

while (running) {
int r, nfds = 0;
fd_set rd;
Expand All @@ -1841,9 +1873,15 @@ main(int argc, char *argv[]) {
FD_ZERO(&rd);
FD_SET(STDIN_FILENO, &rd);

FD_SET(sigwinch_pipe[PIPE_RD], &rd);
nfds = MAX(nfds, sigwinch_pipe[PIPE_RD]);

FD_SET(sigchld_pipe[PIPE_RD], &rd);
nfds = MAX(nfds, sigchld_pipe[PIPE_RD]);

if (cmdfifo.fd != -1) {
FD_SET(cmdfifo.fd, &rd);
nfds = cmdfifo.fd;
nfds = MAX(nfds, cmdfifo.fd);
}

if (bar.fd != -1) {
Expand All @@ -1867,7 +1905,7 @@ main(int argc, char *argv[]) {
}

doupdate();
r = pselect(nfds + 1, &rd, NULL, NULL, NULL, &emptyset);
r = select(nfds + 1, &rd, NULL, NULL, NULL);

if (r < 0) {
if (errno == EINTR)
Expand Down Expand Up @@ -1903,6 +1941,18 @@ main(int argc, char *argv[]) {
continue;
}

if (FD_ISSET(sigwinch_pipe[PIPE_RD], &rd)) {
char buf[512];
while (read(sigwinch_pipe[PIPE_RD], &buf, sizeof(buf)) > 0);
handle_sigwinch();
}

if (FD_ISSET(sigchld_pipe[PIPE_RD], &rd)) {
char buf[512];
while (read(sigchld_pipe[PIPE_RD], &buf, sizeof(buf)) > 0);
handle_sigchld();
}

if (cmdfifo.fd != -1 && FD_ISSET(cmdfifo.fd, &rd))
handle_cmdfifo();

Expand Down