diff --git a/include/r_api.h b/include/r_api.h index 2a4344dfb..19398f240 100644 --- a/include/r_api.h +++ b/include/r_api.h @@ -97,6 +97,8 @@ void start_outputs(struct r_cfg *cfg, char const *const *well_known); void add_sr_dumper(struct r_cfg *cfg, char const *spec, int overwrite); +void reopen_dumpers(struct r_cfg *cfg); + void close_dumpers(struct r_cfg *cfg); void add_dumper(struct r_cfg *cfg, char const *spec, int overwrite); diff --git a/src/r_api.c b/src/r_api.c index 01a5ac2f3..9c01742ac 100644 --- a/src/r_api.c +++ b/src/r_api.c @@ -43,6 +43,10 @@ #include "fatal.h" #include "http_server.h" +#ifndef _WIN32 +#include +#endif + #ifdef _WIN32 #include #include @@ -1154,6 +1158,47 @@ void add_sr_dumper(r_cfg_t *cfg, char const *spec, int overwrite) cfg->sr_execopen = overwrite; } +void reopen_dumpers(struct r_cfg *cfg) +{ +#ifndef _WIN32 + for (void **iter = cfg->demod->dumper.elems; iter && *iter; ++iter) { + file_info_t *dumper = *iter; + if (dumper->file && (dumper->file != stdout)) { + // Get current file inode + struct stat old_st = {0}; + int ret = fstat(fileno(dumper->file), &old_st); + if (ret) { + fprintf(stderr, "Failed to fstat %s (%d)\n", dumper->path, errno); + exit(1); + } + + // Get new path inode if available + struct stat new_st = {0}; + stat(dumper->path, &new_st); + // ok for stat() to fail, the file might not exist + if (old_st.st_ino == new_st.st_ino) { + continue; + } + + // Reopen the file + print_logf(LOG_INFO, "Dumper", "Reopening \"%s\"", dumper->path); + fclose(dumper->file); + dumper->file = fopen(dumper->path, "wb"); + if (!dumper->file) { + fprintf(stderr, "Failed to open %s\n", dumper->path); + exit(1); + } + if (dumper->format == VCD_LOGIC) { + pulse_data_print_vcd_header(dumper->file, cfg->samp_rate); + } + if (dumper->format == PULSE_OOK) { + pulse_data_print_pulse_header(dumper->file); + } + } + } +#endif +} + void close_dumpers(struct r_cfg *cfg) { for (void **iter = cfg->demod->dumper.elems; iter && *iter; ++iter) { diff --git a/src/rtl_433.c b/src/rtl_433.c index 2bb3f6f42..e8fd7691b 100644 --- a/src/rtl_433.c +++ b/src/rtl_433.c @@ -1309,6 +1309,7 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg) } static r_cfg_t g_cfg; +static volatile sig_atomic_t sig_hup; // TODO: SIGINFO is not in POSIX... #ifndef SIGINFO @@ -1347,6 +1348,10 @@ static void sighandler(int signum) write_err("Ignoring received signal SIGPIPE, Broken pipe.\n"); return; } + else if (signum == SIGHUP) { + sig_hup = 1; + return; + } else if (signum == SIGINFO/* TODO: maybe SIGUSR1 */) { g_cfg.stats_now++; return; @@ -1504,6 +1509,10 @@ static void timer_handler(struct mg_connection *nc, int ev, void *ev_data) { //fprintf(stderr, "%s: %d, %d, %p, %p\n", __func__, nc->sock, ev, nc->user_data, ev_data); r_cfg_t *cfg = (r_cfg_t *)nc->user_data; + if (sig_hup) { + reopen_dumpers(cfg); + sig_hup = 0; + } switch (ev) { case MG_EV_TIMER: { double now = *(double *)ev_data; @@ -1988,6 +1997,7 @@ int main(int argc, char **argv) { sigact.sa_handler = sighandler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; + sigaction(SIGHUP, &sigact, NULL); sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL);