diff options
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | daemon.c | 49 | ||||
-rw-r--r-- | gpsd.c | 51 |
4 files changed, 64 insertions, 43 deletions
diff --git a/Makefile.am b/Makefile.am index 95f00a98..46532074 100644 --- a/Makefile.am +++ b/Makefile.am @@ -175,6 +175,10 @@ libgps_c_sources = \ shared_json.c \ strl.c +if NO_DAEMON3 +libgps_c_sources += daemon.c +endif + libgpsd_c_sources = \ bits.c \ bsd-base64.c \ diff --git a/configure.ac b/configure.ac index 332fa677..37519ed8 100644 --- a/configure.ac +++ b/configure.ac @@ -183,6 +183,9 @@ AC_CHECK_FUNCS(strlcpy) AC_CHECK_FUNCS(strlcat) AC_CHECK_FUNCS(setlocale) AC_CHECK_FUNCS(vsnprintf) +AC_CHECK_FUNCS(daemon) + +AM_CONDITIONAL([NO_DAEMON3], [test x"ac_cv_func_daemon" != xyes]) AC_HEADER_TIME AC_STRUCT_TIMEZONE diff --git a/daemon.c b/daemon.c new file mode 100644 index 00000000..22afab68 --- /dev/null +++ b/daemon.c @@ -0,0 +1,49 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifndef S_SPLINT_S +#include <unistd.h> +#endif /* S_SPLINT_S */ + +#include "gpsd_config.h" +#if defined (HAVE_PATH_H) +#include <paths.h> +#else +#if !defined (_PATH_DEVNULL) +#define _PATH_DEVNULL "/dev/null" +#endif +#endif + +int daemon(int nochdir, int noclose) +/* compatible with the daemon(3) found on Linuxes and BSDs */ +{ + int fd; + pid_t pid; + + /*@ -type @*//* weirdly, splint 3.1.2 is confused by fork() */ + switch (pid = fork()) { + case -1: + return -1; + case 0: /* child side */ + break; + default: /* parent side */ + exit(0); + } + /*@ +type @*/ + + if (setsid() == -1) + return -1; + if ((nochdir==0) && (chdir("/") == -1)) + return -1; + /*@ -nullpass @*/ + if ((noclose==0) && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close(fd); + } + /*@ +nullpass @*/ + return 0; +} @@ -38,14 +38,6 @@ #include "gpsd_config.h" -#if defined (HAVE_PATH_H) -#include <paths.h> -#else -#if !defined (_PATH_DEVNULL) -#define _PATH_DEVNULL "/dev/null" -#endif -#endif - #ifdef DBUS_ENABLE #include "gpsd_dbus.h" #endif @@ -170,39 +162,6 @@ static void onsig(int sig) signalled = (sig_atomic_t) sig; } -static int daemonize(void) -{ - int fd; - pid_t pid; - - /*@ -type @*//* weirdly, splint 3.1.2 is confused by fork() */ - switch (pid = fork()) { - case -1: - return -1; - case 0: /* child side */ - break; - default: /* parent side */ - exit(0); - } - /*@ +type @*/ - - if (setsid() == -1) - return -1; - if (chdir("/") == -1) - return -1; - /*@ -nullpass @*/ - if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { - (void)dup2(fd, STDIN_FILENO); - (void)dup2(fd, STDOUT_FILENO); - (void)dup2(fd, STDERR_FILENO); - if (fd > 2) - (void)close(fd); - } - /*@ +nullpass @*/ - in_background = true; - return 0; -} - #if defined(PPS_ENABLE) static pthread_mutex_t report_mutex; #endif /* PPS_ENABLE */ @@ -1628,8 +1587,14 @@ int main(int argc, char *argv[]) control_socket); } - if (go_background) - (void)daemonize(); + /* might be time to daemonize */ + if (go_background) { + /* not SuS/POSIX portable, but we have our own fallback version */ + if (daemon(0, 0) == 0) + in_background = true; + else + gpsd_report(LOG_ERROR,"demonization failed: %s\n",strerror(errno)); + } if (pid_file) { FILE *fp; |