diff --git a/common.c b/common.c index 5b8050eb..8c9869e6 100644 --- a/common.c +++ b/common.c @@ -34,6 +34,7 @@ #include #include #include "common.h" +#include "daemon.h" shairport_cfg config; @@ -41,10 +42,16 @@ int debuglev = 0; void die(char *format, ...) { fprintf(stderr, "FATAL: "); + va_list args; va_start(args, format); + vfprintf(stderr, format, args); + if (config.daemonise) + daemon_fail(format, args); // Send error message to parent + va_end(args); + fprintf(stderr, "\n"); shairport_shutdown(); } diff --git a/daemon.c b/daemon.c index 4b1bb49e..b56ed67d 100644 --- a/daemon.c +++ b/daemon.c @@ -45,16 +45,27 @@ void daemon_init() { die("failed to fork!"); if (pid) { - char buf[8]; + close(daemon_pipe[1]); + + char buf[64]; ret = read(daemon_pipe[0], buf, sizeof(buf)); if (ret < 0) { - printf("Spawning the daemon failed.\n"); + // No response from child, something failed + fprintf(stderr, "Spawning the daemon failed.\n"); exit(1); + } else if (buf[0] != 0) { + // First byte is non zero, child sent error message + write(STDERR_FILENO, buf, ret); + fprintf(stderr, "\n"); + exit(1); + } else { + // Success ! + printf("%d\n", pid); + exit(0); } - - printf("%d\n", pid); - exit(0); } else { + close(daemon_pipe[0]); + if (config.pidfile) { lock_fd = open(config.pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (lock_fd < 0) { @@ -72,12 +83,21 @@ void daemon_init() { } void daemon_ready() { - write(daemon_pipe[1], "ok", 2); + char ok = 0; + write(daemon_pipe[1], &ok, 1); close(daemon_pipe[1]); + daemon_pipe[1] = -1; } +void daemon_fail(const char *format, va_list arg) { + // Are we still initializing ? + if (daemon_pipe[1] > 0) { + vdprintf(daemon_pipe[1], format, arg); + } +} + void daemon_exit() { - if (lock_fd) { + if (lock_fd > 0) { lockf(lock_fd, F_ULOCK, 0); close(lock_fd); unlink(config.pidfile); diff --git a/daemon.h b/daemon.h index 8779571c..ef20cd52 100644 --- a/daemon.h +++ b/daemon.h @@ -3,6 +3,7 @@ void daemon_init(); void daemon_ready(); +void daemon_fail(const char *format, va_list arg); void daemon_exit(); #endif // _DAEMON_H