c++ - start-stop-daemon not sending SIGTERM -


i have simple daemon boils down to

#include <unistd.h> #include <signal.h> #include <sys/stat.h>  #include <fstream> #include <iostream>  #include <boost/thread.hpp>  bool running = true; std::ofstream log_output;  void close_log_output() {     log_output.close(); }  void signal_handler(int) {     running = false; }  int detach_service() {     if(pid_t pid = fork()) exit(pid < 0);     umask(0);     close(stdin_fileno);     close(stdout_fileno);     close(stderr_fileno);     chdir("/");     log_output.open("/var/log/mydaemon.log");     std::cout.rdbuf(log_output.rdbuf());     std::cerr.rdbuf(log_output.rdbuf());     std::clog.rdbuf(log_output.rdbuf());     atexit(&close_log_output);     signal(sigterm, &signal_handler);     return (setsid() < 0); }  int main(int argc, char **argv) {     if(int err = detach_service()) return err;     while(running) boost::this_thread::sleep(boost::posix_time::milliseconds(30));     std::cout << "terminated\n";     return 0; } 

and init.d script original skeleton $name, $daemon , $daemon_args adjusted. if kill process via it's pid receives sigterm , terminates properly, if try stop service (which set send term first default) command hangs , process killed without ever receiving sigterm.

what have do/change process terminated correctly (either on shell side or on c++ side)

the modified skeleton (only name , daemon_args changed in comparison original ubuntu init.d skeleton):

#! /bin/sh ### begin init info # provides:          skeleton # required-start:    $remote_fs $syslog # required-stop:     $remote_fs $syslog # default-start:     2 3 4 5 # default-stop:      0 1 6 # short-description: example initscript # description:       file should used construct scripts #                    placed in /etc/init.d. ### end init info  # author: foo bar <foobar@baz.org> # # please remove "author" lines above , replace them # own name if copy , modify script.  # not "set -e"  # path should include /usr/* if runs after mountnfs.sh script path=/sbin:/usr/sbin:/bin:/usr/bin desc="description of service" name=mydaemon daemon=/usr/sbin/$name daemon_args="" pidfile=/var/run/$name.pid scriptname=/etc/init.d/$name  # exit if package not installed [ -x "$daemon" ] || exit 0  # read configuration variable file if present [ -r /etc/default/$name ] && . /etc/default/$name  # load verbose setting , other rcs variables . /lib/init/vars.sh  # define lsb log_* functions. # depend on lsb-base (>= 3.2-14) ensure file present # , status_of_proc working. . /lib/lsb/init-functions  # # function starts daemon/service # do_start() {         # return         #   0 if daemon has been started         #   1 if daemon running         #   2 if daemon not started         start-stop-daemon --start --quiet --pidfile $pidfile --exec $daemon --test > /dev/null \                 || return 1         start-stop-daemon --start --quiet --pidfile $pidfile --exec $daemon -- \                 $daemon_args \                 || return 2         # add code here, if necessary, waits process ready         # handle requests services started subsequently depend         # on one.  last resort, sleep time. }  # # function stops daemon/service # do_stop() {         # return         #   0 if daemon has been stopped         #   1 if daemon stopped         #   2 if daemon not stopped         #   other if failure occurred         start-stop-daemon --stop --quiet --retry=term/30/kill/5 --pidfile $pidfile --name $name         retval="$?"         [ "$retval" = 2 ] && return 2         # wait children finish if daemon forks         # , if daemon ever run initscript.         # if above conditions not satisfied add other code         # waits process drop resources         # needed services started subsequently.  last resort         # sleep time.         start-stop-daemon --stop --quiet --oknodo --retry=0/30/kill/5 --exec $daemon         [ "$?" = 2 ] && return 2         # many daemons don't delete pidfiles when exit.         rm -f $pidfile         return "$retval" }  # # function sends sighup daemon/service # do_reload() {         #         # if daemon can reload configuration without         # restarting (for example, when sent sighup),         # implement here.         #         start-stop-daemon --stop --signal 1 --quiet --pidfile $pidfile --name $name         return 0 }  case "$1" in   start)         [ "$verbose" != no ] && log_daemon_msg "starting $desc" "$name"         do_start         case "$?" in                 0|1) [ "$verbose" != no ] && log_end_msg 0 ;;                 2) [ "$verbose" != no ] && log_end_msg 1 ;;         esac         ;;   stop)         [ "$verbose" != no ] && log_daemon_msg "stopping $desc" "$name"         do_stop         case "$?" in                 0|1) [ "$verbose" != no ] && log_end_msg 0 ;;                 2) [ "$verbose" != no ] && log_end_msg 1 ;;         esac         ;;   status)         status_of_proc "$daemon" "$name" && exit 0 || exit $?         ;;   #reload|force-reload)         #         # if do_reload() not implemented leave commented out         # , leave 'force-reload' alias 'restart'.         #         #log_daemon_msg "reloading $desc" "$name"         #do_reload         #log_end_msg $?         #;;   restart|force-reload)         #         # if "reload" option implemented remove         # 'force-reload' alias         #         log_daemon_msg "restarting $desc" "$name"         do_stop         case "$?" in           0|1)                 do_start                 case "$?" in                         0) log_end_msg 0 ;;                         1) log_end_msg 1 ;; # old process still running                         *) log_end_msg 1 ;; # failed start                 esac                 ;;           *)                 # failed stop                 log_end_msg 1                 ;;         esac         ;;   *)         #echo "usage: $scriptname {start|stop|restart|reload|force-reload}" >&2         echo "usage: $scriptname {start|stop|status|restart|force-reload}" >&2         exit 3         ;; esac  : 

your daemon not create pidfile, , neither start-stop-daemon. guess first line

start-stop-daemon --stop --quiet --retry=term/30/kill/5 --pidfile $pidfile --name $name 

does nothing, because --pidfile process selection criterion never satisfied, second line

start-stop-daemon --stop --quiet --oknodo --retry=0/30/kill/5 --exec $daemon 

kills daemon sigkill, because here --pidfile option not included.

you should fix daemon create pidfile.


Comments

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -