From 2d0db49d0f44af56a1d486d8647338b34d91bd05 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 12 Mar 2022 08:20:08 +0200 Subject: [PATCH] - implemented save/restore cfg protocol handling. - made SIGHUP handling safer, by moving the cfg re-read into the select loop, and triggering it with a self-pipe write. --- src/proto_unix.c | 11 ++++++++++ src/spnavd.c | 52 +++++++++++++++++++++++++++++++++--------------- src/spnavd.h | 6 +++++- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/src/proto_unix.c b/src/proto_unix.c index 57872bb..f9771ca 100644 --- a/src/proto_unix.c +++ b/src/proto_unix.c @@ -513,6 +513,17 @@ static int handle_request(struct client *c, struct reqresp *req) sendresp(c, req, 0); break; + case REQ_CFG_SAVE: + sendresp(c, req, write_cfg(cfgfile, &cfg)); + break; + + case REQ_CFG_RESTORE: + if(read_cfg(cfgfile, &cfg) == -1) { + default_cfg(&cfg); + } + cfg_changed(); + break; + default: logmsg(LOG_WARNING, "invalid client request: %04xh\n", (unsigned int)req->type); sendresp(c, req, -1); diff --git a/src/spnavd.c b/src/spnavd.c index fd081ca..77f612c 100644 --- a/src/spnavd.c +++ b/src/spnavd.c @@ -47,8 +47,9 @@ static void handle_events(fd_set *rset); static void sig_handler(int s); static char *fix_path(char *str); -static char *cfgfile = DEF_CFGFILE; +char *cfgfile = DEF_CFGFILE; static char *logfile = DEF_LOGFILE; +static int pfd[2]; int main(int argc, char **argv) { @@ -146,6 +147,8 @@ int main(int argc, char **argv) logmsg(LOG_INFO, "Spacenav daemon " VERSION "\n"); read_cfg(cfgfile, &cfg); + prev_cfg = cfg; + pipe(pfd); signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); @@ -214,6 +217,10 @@ int main(int argc, char **argv) } #endif + /* also the self-pipe read-end for safe SIGHUP handling */ + FD_SET(pfd[0], &rset); + if(pfd[0] > max_fd) max_fd = fd; + do { /* if there is at least one device out of the deadzone and repeat is enabled * wait for only as long as specified in cfg.repeat_msec @@ -389,6 +396,15 @@ static void handle_events(fd_set *rset) struct device *dev; struct dev_input inp; + /* handle signal pipe */ + if(FD_ISSET(pfd[0], rset)) { + int tmp; + read(pfd[0], &tmp, sizeof tmp); /* eat up the junk char */ + + read_cfg(cfgfile, &cfg); + cfg_changed(); + } + /* handle anything coming through the UNIX socket */ handle_uevents(rset); @@ -422,28 +438,32 @@ static void handle_events(fd_set *rset) } } +void cfg_changed(void) +{ + if(cfg.led != prev_cfg.led) { + struct device *dev = get_devices(); + while(dev) { + if(is_device_valid(dev)) { + if(verbose) { + logmsg(LOG_INFO, "turn led %s, device: %s\n", cfg.led ? "on": "off", dev->name); + } + set_device_led(dev, cfg.led); + } + dev = dev->next; + } + } + + prev_cfg = cfg; +} + /* signals usr1 & usr2 are sent by the spnav_x11 script to start/stop the * daemon's connection to the X server. */ static void sig_handler(int s) { - int prev_led = cfg.led; - switch(s) { case SIGHUP: - read_cfg(cfgfile, &cfg); - if(cfg.led != prev_led) { - struct device *dev = get_devices(); - while(dev) { - if(is_device_valid(dev)) { - if(verbose) { - logmsg(LOG_INFO, "turn led %s, device: %s\n", cfg.led ? "on": "off", dev->name); - } - set_device_led(dev, cfg.led); - } - dev = dev->next; - } - } + write(pfd[1], &s, 1); /* write *something* to the pipe to trigger a re-read */ break; case SIGSEGV: diff --git a/src/spnavd.h b/src/spnavd.h index 45662ab..89e2c65 100644 --- a/src/spnavd.h +++ b/src/spnavd.h @@ -49,7 +49,11 @@ along with this program. If not, see . -struct cfg cfg; +struct cfg cfg, prev_cfg; +extern char *cfgfile; /* defined in spnavd.c */ + int verbose; +void cfg_changed(void); + #endif /* SPNAVD_H_ */