diff --git a/src/cfgfile.c b/src/cfgfile.c index 7602a9f..98ede81 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -66,9 +66,6 @@ void default_cfg(struct cfg *cfg) cfg->devname[i] = 0; cfg->devid[i][0] = cfg->devid[i][1] = -1; } - - cfg->use_logfile = 1; - cfg->use_syslog = 1; } #define EXPECT(cond) \ @@ -315,13 +312,6 @@ int read_cfg(const char *fname, struct cfg *cfg) continue; } - } else if(strcmp(key_str, "logfile") == 0) { - strncpy(cfg->logfile, val_str, PATH_MAX - 1); - - } else if(strcmp(key_str, "log") == 0) { - cfg->use_logfile = strstr(val_str, "file") == 0 ? 1 : 0; - cfg->use_syslog = strstr(val_str, "syslog") == 0 ? 1 : 0; - } else { logmsg(LOG_WARNING, "unrecognized config option: %s\n", key_str); } @@ -473,33 +463,6 @@ int write_cfg(const char *fname, struct cfg *cfg) } fprintf(fp, "\n"); - fprintf(fp, "# Log file path\n"); - if(cfg->logfile[0]) { - fprintf(fp, "logfile = %s\n\n", cfg->logfile); - } else { - fprintf(fp, "#logfile = " DEF_LOGFILE "\n\n"); - } - - fprintf(fp, "# Log targets\n"); - fprintf(fp, "#\n"); - fprintf(fp, "# Valid options are:\n"); - fprintf(fp, "# - file: log messages to a file defined by the logfile option.\n"); - fprintf(fp, "# - syslog: log messages to the system logging daemon.\n"); - fprintf(fp, "# Combine multiple options by listing them on the same line.\n"); - fprintf(fp, "#\n"); - if(cfg->use_logfile || cfg->use_syslog) { - fprintf(fp, "log ="); - if(cfg->use_logfile) { - fprintf(fp, " file"); - } - if(cfg->use_syslog) { - fprintf(fp, " syslog"); - } - fputc('\n', fp); - } else { - fprintf(fp, "#log = file, syslog\n"); - } - /* unlock */ flk.l_type = F_UNLCK; flk.l_start = flk.l_len = 0; diff --git a/src/cfgfile.h b/src/cfgfile.h index 586d2a5..ed87f55 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2018 John Tsiombikas +Copyright (C) 2007-2019 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,9 +45,6 @@ struct cfg { char *devname[MAX_CUSTOM]; /* custom USB device name list */ int devid[MAX_CUSTOM][2]; /* custom USB vendor/product id list */ - - char logfile[PATH_MAX]; - int use_logfile, use_syslog; }; void default_cfg(struct cfg *cfg); diff --git a/src/dev_usb_linux.c b/src/dev_usb_linux.c index d7b8432..3b60aed 100644 --- a/src/dev_usb_linux.c +++ b/src/dev_usb_linux.c @@ -311,7 +311,7 @@ struct usb_device_info *find_usb_devices(int (*match)(const struct usb_device_in buf_len = sizeof(buf) - 1; if(!(fp = fopen(PROC_DEV, "r"))) { if(verbose) { - logmsg(LOG_ERR, "failed to open " PROC_DEV); + logmsg(LOG_ERR, "failed to open " PROC_DEV ": %s\n", strerror(errno)); } goto alt_detect; } diff --git a/src/logger.c b/src/logger.c index 33ea90a..553ce66 100644 --- a/src/logger.c +++ b/src/logger.c @@ -36,6 +36,7 @@ int start_logfile(const char *fname) int start_syslog(const char *id) { openlog(id, LOG_NDELAY, LOG_DAEMON); + use_syslog = 1; return 0; } @@ -43,22 +44,11 @@ void logmsg(int prio, const char *fmt, ...) { va_list ap; - /* if a logfile isn't open, assume we are not daemonized, and try to output - * to stdout/stderr as usual. If we are daemonized but don't have a log file - * this will end up writing harmlessly to /dev/null (see daemonize in spnavd.c) - */ - va_start(ap, fmt); if(logfile) { + va_start(ap, fmt); vfprintf(logfile, fmt, ap); - } else { - if(prio <= LOG_WARNING) { - vfprintf(stderr, fmt, ap); - } else { - vprintf(fmt, ap); - } + va_end(ap); } - va_end(ap); - if(use_syslog) { va_start(ap, fmt); vsyslog(prio, fmt, ap); diff --git a/src/spnavd.c b/src/spnavd.c index 106c108..deaab68 100644 --- a/src/spnavd.c +++ b/src/spnavd.c @@ -45,6 +45,7 @@ static void handle_events(fd_set *rset); static void sig_handler(int s); static const char *cfgfile = DEF_CFGFILE; +static const char *logfile = DEF_LOGFILE; int main(int argc, char **argv) { @@ -65,6 +66,18 @@ int main(int argc, char **argv) cfgfile = argv[i]; break; + case 'l': + if(!argv[++i]) { + fprintf(stderr, "-l must be followed by a logfile name or \"syslog\"\n"); + return 1; + } + if(strcmp(argv[i], "syslog") == 0) { + logfile = 0; + } else { + logfile = argv[i]; + } + break; + case 'v': verbose = 1; break; @@ -72,10 +85,11 @@ int main(int argc, char **argv) case 'h': printf("usage: %s [options]\n", argv[0]); printf("options:\n"); - printf(" -d do not daemonize\n"); - printf(" -c config file path (default: " DEF_CFGFILE ")\n"); - printf(" -v verbose output\n"); - printf(" -h print usage information and exit\n"); + printf(" -d: do not daemonize\n"); + printf(" -c : config file path (default: " DEF_CFGFILE ")\n"); + printf(" -l |syslog: log file path or log to syslog (default: " DEF_LOGFILE ")\n"); + printf(" -v: verbose output\n"); + printf(" -h: print usage information and exit\n"); return 0; default: @@ -102,15 +116,6 @@ int main(int argc, char **argv) read_cfg(cfgfile, &cfg); - if(become_daemon) { - if(cfg.use_syslog) { - start_syslog(SYSLOG_ID); - } - if(cfg.use_logfile) { - start_logfile(cfg.logfile[0] ? cfg.logfile : DEF_LOGFILE); - } - } - signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGSEGV, sig_handler); @@ -250,14 +255,24 @@ static void daemonize(void) setsid(); chdir("/"); - /* redirect standard input/output/error */ + /* redirect standard input/output/error + * best effort attempt to make either the logfile or the syslog socket + * accessible through stdout/stderr, just in case any printfs survived + * the logmsg conversion. + */ for(i=0; i<3; i++) { close(i); } open("/dev/zero", O_RDONLY); - open("/dev/null", O_WRONLY); + + if(!logfile || start_logfile(logfile) == -1) { + start_syslog(SYSLOG_ID); + } dup(1); + + setvbuf(stdout, 0, _IOLBF, 0); + setvbuf(stderr, 0, _IONBF, 0); } static int write_pid_file(void)