X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fdaemon.c;h=c72aa302f82ec74f0578e23370619f3d53b2e726;hb=185071b355f704ffe9072b3221eedbda78558dda;hp=a3a6ab12a0c31b9e9ee6096794f4d7176ca90190;hpb=906a9c59f8c77f4002616a34b0b98d91d8b1bbc5;p=yaz-moved-to-github.git diff --git a/src/daemon.c b/src/daemon.c index a3a6ab1..c72aa30 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,8 +1,6 @@ -/* - * Copyright (C) 1995-2008, Index Data ApS +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2012 Index Data * See the file LICENSE for details. - * - * $Id: daemon.c,v 1.1 2008-02-18 17:07:06 adam Exp $ */ /** @@ -17,20 +15,33 @@ #include #include #include +#if HAVE_UNISTD_H #include -#include +#endif #include -#include +#if HAVE_SYS_WAIT_H #include +#endif + +#if HAVE_SYS_TYPES_H #include -#include +#endif + #include + +#if HAVE_PWD_H #include +#endif + +#if HAVE_SYS_PRCTL_H +#include +#endif #include #include #include +#if HAVE_PWD_H static void write_pidfile(int pid_fd) { if (pid_fd != -1) @@ -42,7 +53,7 @@ static void write_pidfile(int pid_fd) yaz_log(YLOG_FATAL|YLOG_ERRNO, "ftruncate"); exit(1); } - if (write(pid_fd, buf, strlen(buf)) != strlen(buf)) + if (write(pid_fd, buf, strlen(buf)) != (int) strlen(buf)) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "write"); exit(1); @@ -51,11 +62,31 @@ static void write_pidfile(int pid_fd) } } +int child_got_signal_from_us = 0; pid_t child_pid = 0; -static void kill_child_handler(int num) +static void normal_stop_handler(int num) { if (child_pid) + { + /* tell child to terminate . ensure keepalive stops running - + let wait(2) wait once - so we exit AFTER the child */ + child_got_signal_from_us = 1; kill(child_pid, num); + } +} + +static void graceful_stop_handler(int num) +{ + if (child_pid) + { + /* tell our child to stop listening and wait some in time + in the hope that it has stopped listening by then. Then + we exit - quite possibly the child is still running - serving + remaining requests */ + kill(child_pid, num); + sleep(2); + _exit(0); + } } static void keepalive(void (*work)(void *data), void *data) @@ -64,13 +95,15 @@ static void keepalive(void (*work)(void *data), void *data) int cont = 1; void (*old_sighup)(int); void (*old_sigterm)(int); + void (*old_sigusr1)(int); /* keep signals in their original state and make sure that some signals to parent process also gets sent to the child.. */ - old_sighup = signal(SIGHUP, kill_child_handler); - old_sigterm = signal(SIGTERM, kill_child_handler); - while (cont) + old_sighup = signal(SIGHUP, normal_stop_handler); + old_sigterm = signal(SIGTERM, normal_stop_handler); + old_sigusr1 = signal(SIGUSR1, graceful_stop_handler); + while (cont && !child_got_signal_from_us) { pid_t p = fork(); pid_t p1; @@ -86,6 +119,7 @@ static void keepalive(void (*work)(void *data), void *data) /* child */ signal(SIGHUP, old_sighup); /* restore */ signal(SIGTERM, old_sigterm);/* restore */ + signal(SIGUSR1, old_sigusr1);/* restore */ work(data); exit(0); @@ -134,26 +168,28 @@ static void keepalive(void (*work)(void *data), void *data) yaz_log(YLOG_WARN, "Received SIG %d from child %ld", WTERMSIG(status), (long) p); cont = 0; - } - } - else if (status == 0) - cont = 0; /* child exited normally */ - else - { /* child exited with error */ - yaz_log(YLOG_LOG, "Exit %d from child %ld", status, (long) p); - cont = 0; } + } + else if (status == 0) + cont = 0; /* child exited normally */ + else + { /* child exited with error */ + yaz_log(YLOG_LOG, "Exit %d from child %ld", status, (long) p); + cont = 0; + } if (cont) /* respawn slower as we get more errors */ - sleep(1 + run/5); + sleep(1 + run/5); run++; } } +#endif int yaz_daemon(const char *progname, unsigned int flags, void (*work)(void *data), void *data, const char *pidfile, const char *uid) { +#if HAVE_PWD_H int pid_fd = -1; /* open pidfile .. defer write until in child and after setuid */ @@ -190,6 +226,13 @@ int yaz_daemon(const char *progname, yaz_log(YLOG_FATAL|YLOG_ERRNO, "setuid"); exit(1); } + /* Linux don't produce core dumps evern if the limit is right and + files are writable.. This fixes this. See prctl(2) */ +#if HAVE_SYS_PRCTL_H +#ifdef PR_SET_DUMPABLE + prctl(PR_SET_DUMPABLE, 1, 0, 0); +#endif +#endif } if (flags & YAZ_DAEMON_FORK) @@ -234,7 +277,10 @@ int yaz_daemon(const char *progname, close(1); close(2); open("/dev/null", O_RDWR); - dup(0); dup(0); + if (dup(0) == -1) + return 1; + if (dup(0) == -1) + return 1; close(hand[1]); } @@ -249,12 +295,18 @@ int yaz_daemon(const char *progname, work(data); } return 0; +#else + work(data); + return 0; +#endif } /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab */ +