wmsl

Block-based window manager status line
git clone https://git.sinitax.com/sinitax/wmsl
Log | Files | Refs | README | LICENSE | sfeed.txt

commit 65f9404a4938904bb2971987ba1a89ebb1dae4bf
parent 9806aff5927a13ef6b84ac4f6bd41509a4954500
Author: Louis Burda <quent.burda@gmail.com>
Date:   Fri,  1 Jul 2022 20:10:31 +0200

Replace popen() with fork() to kill after timeout

Diffstat:
Mwmsl.c | 40+++++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/wmsl.c b/wmsl.c @@ -1,6 +1,7 @@ #include <X11/Xlib.h> #include <unistd.h> +#include <err.h> #include <signal.h> #include <time.h> #include <math.h> @@ -92,6 +93,31 @@ concat_status(const char *text, size_t len) status_text[status_len] = '\0'; } +int +run_block(const char *cmd, pid_t *pid) +{ + int input[2]; + + if (pipe(input) == -1) + err(EXIT_FAILURE, "pipe"); + + *pid = fork(); + if (*pid < 0) err(EXIT_FAILURE, "fork"); + + if (*pid != 0) { + close(input[0]); + } else { + dup2(input[0], 0); + close(input[0]); + close(input[1]); + close(0); + close(1); + exit(system(cmd)); + } + + return input[1]; +} + bool read_statusline(int fd, char *buf, size_t size) { @@ -122,9 +148,9 @@ read_statusline(int fd, char *buf, size_t size) void update_blocks(void) { - FILE *cmd; - int i, output_len, update; + int i, fd, output_len, update; char tmp_output[OUTPUTMAX]; + pid_t child; debug("checking block output..\n"); @@ -139,17 +165,14 @@ update_blocks(void) blocks[i].flags = IDLE; /* get command output */ - cmd = popen(blocks[i].command, "r"); - if (!cmd) continue; + fd = run_block(blocks[i].command, &child); - if (!read_statusline(fileno(cmd), tmp_output, OUTPUTMAX)) { + if (!read_statusline(fd, tmp_output, OUTPUTMAX)) { output_len = 0; } else { output_len = strlen(tmp_output); } - pclose(cmd); - if (output_len != strlen(blocks[i].output) || strncmp(tmp_output, blocks[i].output, output_len)) { memcpy(blocks[i].output, tmp_output, output_len); @@ -157,6 +180,9 @@ update_blocks(void) debug("new output from cmd: %s\n", blocks[i].command); update = 1; } + + kill(child, SIGKILL); + close(fd); } else { output_len = strlen(blocks[i].output); }