X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdaemon-windows.c;h=f94ad9bd0fdca835171999b8cceb3c825b966100;hb=0ef165ecb57943e17a8ee8270df68ffb8d032e29;hp=8c284e4e6fedf54f1ca9a94a6e0ea39e25f92f06;hpb=4ec4776c69d44acb3379e663ca700fd7ab3aecb2;p=sliver-openvswitch.git diff --git a/lib/daemon-windows.c b/lib/daemon-windows.c index 8c284e4e6..f94ad9bd0 100644 --- a/lib/daemon-windows.c +++ b/lib/daemon-windows.c @@ -16,12 +16,13 @@ #include #include "daemon.h" +#include "daemon-private.h" #include #include #include "poll-loop.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(daemon); +VLOG_DEFINE_THIS_MODULE(daemon_windows); static bool service_create; /* Was --service specified? */ static bool service_started; /* Have we dispatched service to start? */ @@ -30,9 +31,12 @@ static bool service_started; /* Have we dispatched service to start? */ * unexpectedly? */ static bool monitor; -static bool detach; /* Was --detach specified? */ -static bool detached; /* Running as the child process. */ -static HANDLE write_handle; /* End of pipe to write to parent. */ +bool detach; /* Was --detach specified? */ +static bool detached; /* Running as the child process. */ +static HANDLE write_handle; /* End of pipe to write to parent. */ + +char *pidfile; /* --pidfile: Name of pidfile (null if none). */ +static FILE *filep_pidfile; /* File pointer to access the pidfile. */ /* Handle to the Services Manager and the created service. */ static SC_HANDLE manager, service; @@ -392,25 +396,55 @@ detach_process(int argc, char *argv[]) exit(0); } -/* Will daemonize() really detach? */ -bool -get_detach() +static void +unlink_pidfile(void) { - return detach; + if (filep_pidfile) { + fclose(filep_pidfile); + } + if (pidfile) { + unlink(pidfile); + } } -void -daemon_save_fd(int fd OVS_UNUSED) +/* If a pidfile has been configured, creates it and stores the running + * process's pid in it. Ensures that the pidfile will be deleted when the + * process exits. */ +static void +make_pidfile(void) { -} + int error; + + error = GetFileAttributes(pidfile); + if (error != INVALID_FILE_ATTRIBUTES) { + /* pidfile exists. Try to unlink() it. */ + error = unlink(pidfile); + if (error) { + VLOG_FATAL("Failed to delete existing pidfile %s (%s)", pidfile, + ovs_strerror(errno)); + } + } -void -daemonize(void) -{ + filep_pidfile = fopen(pidfile, "w"); + if (filep_pidfile == NULL) { + VLOG_FATAL("failed to open %s (%s)", pidfile, ovs_strerror(errno)); + } + + fatal_signal_add_hook(unlink_pidfile, NULL, NULL, true); + + fprintf(filep_pidfile, "%d\n", _getpid()); + if (fflush(filep_pidfile) == EOF) { + VLOG_FATAL("Failed to write into the pidfile %s", pidfile); + } + + /* Don't close the pidfile till the process exits. */ } void daemonize_start(void) { + if (pidfile) { + make_pidfile(); + } } void @@ -420,6 +454,9 @@ daemonize_complete(void) * communicate with the parent to inform that the child is ready. */ if (detached) { int error; + + close_standard_fds(); + error = WriteFile(write_handle, "a", 1, NULL, NULL); if (!error) { VLOG_FATAL("Failed to communicate with the parent (%s)", @@ -429,3 +466,15 @@ daemonize_complete(void) service_complete(); } + +/* Returns the file name that would be used for a pidfile if 'name' were + * provided to set_pidfile(). The caller must free the returned string. */ +char * +make_pidfile_name(const char *name) +{ + if (name && strchr(name, ':')) { + return strdup(name); + } else { + return xasprintf("%s/%s.pid", ovs_rundir(), program_name); + } +}