i3bar: Introduce i3bar_child struct

This commit is contained in:
Quentin Glidic 2012-09-03 10:23:25 +02:00 committed by Michael Stapelberg
parent 310ae2d0b5
commit 34dc6d4d64
2 changed files with 34 additions and 24 deletions

View File

@ -12,6 +12,17 @@
#define STDIN_CHUNK_SIZE 1024 #define STDIN_CHUNK_SIZE 1024
typedef struct {
pid_t pid;
/**
* The version number is an uint32_t to avoid machines with different sizes of
* 'int' to allow different values here. Its highly unlikely we ever exceed
* even an int8_t, but still
*/
uint32_t version;
} i3bar_child;
/* /*
* Start a child-process with the specified command and reroute stdin. * Start a child-process with the specified command and reroute stdin.
* We actually start a $SHELL to execute the command so we don't have to care * We actually start a $SHELL to execute the command so we don't have to care

View File

@ -25,14 +25,13 @@
#include "common.h" #include "common.h"
/* Global variables for child_*() */ /* Global variables for child_*() */
pid_t child_pid; i3bar_child child = { 0 };
/* stdin- and sigchild-watchers */ /* stdin- and sigchild-watchers */
ev_io *stdin_io; ev_io *stdin_io;
ev_child *child_sig; ev_child *child_sig;
/* JSON parser for stdin */ /* JSON parser for stdin */
bool plaintext = false;
yajl_callbacks callbacks; yajl_callbacks callbacks;
yajl_handle parser; yajl_handle parser;
@ -68,6 +67,8 @@ void cleanup(void) {
ev_child_stop(main_loop, child_sig); ev_child_stop(main_loop, child_sig);
FREE(child_sig); FREE(child_sig);
} }
memset(&child, 0, sizeof(i3bar_child));
} }
/* /*
@ -224,7 +225,7 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
unsigned char *buffer = get_buffer(watcher, &rec); unsigned char *buffer = get_buffer(watcher, &rec);
if (buffer == NULL) if (buffer == NULL)
return; return;
if (!plaintext) { if (child.version > 0) {
read_json_input(buffer, rec); read_json_input(buffer, rec);
} else { } else {
read_flat_input((char*)buffer, rec); read_flat_input((char*)buffer, rec);
@ -248,15 +249,15 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
unsigned int consumed = 0; unsigned int consumed = 0;
/* At the moment, we dont care for the version. This might change /* At the moment, we dont care for the version. This might change
* in the future, but for now, we just discard it. */ * in the future, but for now, we just discard it. */
plaintext = (determine_json_version(buffer, rec, &consumed) == -1); child.version = determine_json_version(buffer, rec, &consumed);
if (plaintext) { if (child.version > 0) {
read_json_input(buffer + consumed, rec - consumed);
} else {
/* In case of plaintext, we just add a single block and change its /* In case of plaintext, we just add a single block and change its
* full_text pointer later. */ * full_text pointer later. */
struct status_block *new_block = scalloc(sizeof(struct status_block)); struct status_block *new_block = scalloc(sizeof(struct status_block));
TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks); TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks);
read_flat_input((char*)buffer, rec); read_flat_input((char*)buffer, rec);
} else {
read_json_input(buffer + consumed, rec - consumed);
} }
free(buffer); free(buffer);
ev_io_stop(main_loop, stdin_io); ev_io_stop(main_loop, stdin_io);
@ -272,7 +273,7 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
*/ */
void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) { void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) {
ELOG("Child (pid: %d) unexpectedly exited with status %d\n", ELOG("Child (pid: %d) unexpectedly exited with status %d\n",
child_pid, child.pid,
watcher->rstatus); watcher->rstatus);
cleanup(); cleanup();
} }
@ -300,14 +301,13 @@ void start_child(char *command) {
parser = yajl_alloc(&callbacks, NULL, &parser_context); parser = yajl_alloc(&callbacks, NULL, &parser_context);
#endif #endif
child_pid = 0;
if (command != NULL) { if (command != NULL) {
int fd[2]; int fd[2];
if (pipe(fd) == -1) if (pipe(fd) == -1)
err(EXIT_FAILURE, "pipe(fd)"); err(EXIT_FAILURE, "pipe(fd)");
child_pid = fork(); child.pid = fork();
switch (child_pid) { switch (child.pid) {
case -1: case -1:
ELOG("Couldn't fork(): %s\n", strerror(errno)); ELOG("Couldn't fork(): %s\n", strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -349,7 +349,7 @@ void start_child(char *command) {
/* We must cleanup, if the child unexpectedly terminates */ /* We must cleanup, if the child unexpectedly terminates */
child_sig = smalloc(sizeof(ev_child)); child_sig = smalloc(sizeof(ev_child));
ev_child_init(child_sig, &child_sig_cb, child_pid, 0); ev_child_init(child_sig, &child_sig_cb, child.pid, 0);
ev_child_start(main_loop, child_sig); ev_child_start(main_loop, child_sig);
atexit(kill_child_at_exit); atexit(kill_child_at_exit);
@ -360,9 +360,9 @@ void start_child(char *command) {
* *
*/ */
void kill_child_at_exit(void) { void kill_child_at_exit(void) {
if (child_pid != 0) { if (child.pid > 0) {
kill(child_pid, SIGCONT); kill(child.pid, SIGCONT);
kill(child_pid, SIGTERM); kill(child.pid, SIGTERM);
} }
} }
@ -372,12 +372,11 @@ void kill_child_at_exit(void) {
* *
*/ */
void kill_child(void) { void kill_child(void) {
if (child_pid != 0) { if (child.pid > 0) {
kill(child_pid, SIGCONT); kill(child.pid, SIGCONT);
kill(child_pid, SIGTERM); kill(child.pid, SIGTERM);
int status; int status;
waitpid(child_pid, &status, 0); waitpid(child.pid, &status, 0);
child_pid = 0;
cleanup(); cleanup();
} }
} }
@ -387,8 +386,8 @@ void kill_child(void) {
* *
*/ */
void stop_child(void) { void stop_child(void) {
if (child_pid != 0) { if (child.pid > 0) {
kill(child_pid, SIGSTOP); kill(child.pid, SIGSTOP);
} }
} }
@ -397,7 +396,7 @@ void stop_child(void) {
* *
*/ */
void cont_child(void) { void cont_child(void) {
if (child_pid != 0) { if (child.pid > 0) {
kill(child_pid, SIGCONT); kill(child.pid, SIGCONT);
} }
} }