Don't link to rt anymore as it makes dlopen leak - we now use nanosleeps to achieve the same goal (a loop + timeout). No longer put / at the end of directories, instead prefix like so RC_LIBDIR "/foo" to ensure more robust code.
This commit is contained in:
parent
9072ce748f
commit
0084bc41ef
@ -70,7 +70,6 @@ endif
|
||||
ifeq ($(OS),Linux)
|
||||
LDLIBS_RC = -ldl
|
||||
LDLIBS_RS = -ldl
|
||||
LDLIBS_SSD = -lrt
|
||||
# Shouldn't need this, but it's the easiest workaround for silly
|
||||
# Linux headers that don't work with -std=c99
|
||||
override CPPFLAGS += -D_GNU_SOURCE
|
||||
|
@ -582,17 +582,17 @@ static const deppair_t deppairs[] = {
|
||||
|
||||
static const char *depdirs[] =
|
||||
{
|
||||
RC_SVCDIR "starting",
|
||||
RC_SVCDIR "started",
|
||||
RC_SVCDIR "stopping",
|
||||
RC_SVCDIR "inactive",
|
||||
RC_SVCDIR "wasinactive",
|
||||
RC_SVCDIR "failed",
|
||||
RC_SVCDIR "coldplugged",
|
||||
RC_SVCDIR "daemons",
|
||||
RC_SVCDIR "options",
|
||||
RC_SVCDIR "exclusive",
|
||||
RC_SVCDIR "scheduled",
|
||||
RC_SVCDIR "/starting",
|
||||
RC_SVCDIR "/started",
|
||||
RC_SVCDIR "/stopping",
|
||||
RC_SVCDIR "/inactive",
|
||||
RC_SVCDIR "/wasinactive",
|
||||
RC_SVCDIR "/failed",
|
||||
RC_SVCDIR "/coldplugged",
|
||||
RC_SVCDIR "/daemons",
|
||||
RC_SVCDIR "/options",
|
||||
RC_SVCDIR "/exclusive",
|
||||
RC_SVCDIR "/scheduled",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -9,11 +9,11 @@
|
||||
#define ERRX eerrorx("out of memory");
|
||||
|
||||
#define PROFILE_ENV "/etc/profile.env"
|
||||
#define SYS_WHITELIST RC_LIBDIR "conf.d/env_whitelist"
|
||||
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
|
||||
#define USR_WHITELIST "/etc/conf.d/env_whitelist"
|
||||
#define RC_CONFIG "/etc/conf.d/rc"
|
||||
|
||||
#define PATH_PREFIX RC_LIBDIR "bin:/bin:/sbin:/usr/bin:/usr/sbin"
|
||||
#define PATH_PREFIX RC_LIBDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"
|
||||
|
||||
#ifndef S_IXUGO
|
||||
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
@ -95,30 +95,33 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...)
|
||||
if (! path1 || ! paths)
|
||||
return (NULL);
|
||||
|
||||
length = strlen (path1) + strlen (paths) + 3;
|
||||
i = 0;
|
||||
va_start (ap, paths);
|
||||
while ((p = va_arg (ap, char *)) != NULL)
|
||||
length += strlen (p) + 1;
|
||||
va_end (ap);
|
||||
|
||||
path = rc_xmalloc (length);
|
||||
memset (path, 0, length);
|
||||
memcpy (path, path1, strlen (path1));
|
||||
pathp = path + strlen (path1) - 1;
|
||||
if (*pathp != '/') {
|
||||
pathp++;
|
||||
*pathp++ = '/';
|
||||
}
|
||||
else
|
||||
pathp++;
|
||||
memcpy (pathp, paths, strlen (paths));
|
||||
pathp += strlen (paths);
|
||||
length = strlen (path1) + strlen (paths) + 1;
|
||||
if (*paths != '/')
|
||||
length ++;
|
||||
|
||||
va_start (ap, paths);
|
||||
while ((p = va_arg (ap, char *)) != NULL) {
|
||||
if (*pathp != '/')
|
||||
*pathp++ = '/';
|
||||
if (*p != '/')
|
||||
length ++;
|
||||
length += strlen (p);
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
pathp = path = rc_xmalloc (length * sizeof (char *));
|
||||
memset (path, 0, length);
|
||||
i = strlen (path1);
|
||||
memcpy (path, path1, i);
|
||||
pathp += i;
|
||||
if (*paths != '/')
|
||||
*pathp ++ = '/';
|
||||
i = strlen (paths);
|
||||
memcpy (pathp, paths, i);
|
||||
pathp += i;
|
||||
|
||||
va_start (ap, paths);
|
||||
while ((p = va_arg (ap, char *)) != NULL) {
|
||||
if (*p != '/')
|
||||
*pathp ++= '/';
|
||||
i = strlen (p);
|
||||
memcpy (pathp, p, i);
|
||||
pathp += i;
|
||||
@ -615,14 +618,14 @@ char **rc_config_env (char **env)
|
||||
rc_strlist_free (config);
|
||||
|
||||
/* One char less to drop the trailing / */
|
||||
i = strlen ("RC_LIBDIR=") + strlen (RC_LIBDIR);
|
||||
i = strlen ("RC_LIBDIR=") + strlen (RC_LIBDIR) + 1;
|
||||
line = rc_xmalloc (sizeof (char *) * i);
|
||||
snprintf (line, i, "RC_LIBDIR=" RC_LIBDIR);
|
||||
env = rc_strlist_add (env, line);
|
||||
free (line);
|
||||
|
||||
/* One char less to drop the trailing / */
|
||||
i = strlen ("RC_SVCDIR=") + strlen (RC_SVCDIR);
|
||||
i = strlen ("RC_SVCDIR=") + strlen (RC_SVCDIR) + 1;
|
||||
line = rc_xmalloc (sizeof (char *) * i);
|
||||
snprintf (line, i, "RC_SVCDIR=" RC_SVCDIR);
|
||||
env = rc_strlist_add (env, line);
|
||||
|
59
src/librc.c
59
src/librc.c
@ -8,12 +8,12 @@
|
||||
#include "librc.h"
|
||||
|
||||
/* usecs to wait while we poll the fifo */
|
||||
#define WAIT_INTERVAL 20000
|
||||
#define WAIT_INTERVAL 20000000
|
||||
|
||||
/* max secs to wait until a service comes up */
|
||||
#define WAIT_MAX 60
|
||||
/* max nsecs to wait until a service comes up */
|
||||
#define WAIT_MAX 60000000000
|
||||
|
||||
#define SOFTLEVEL RC_SVCDIR "softlevel"
|
||||
#define SOFTLEVEL RC_SVCDIR "/softlevel"
|
||||
|
||||
/* File stream used for plugins to write environ vars to */
|
||||
FILE *rc_environ_fd = NULL;
|
||||
@ -33,13 +33,13 @@ static const char *rc_service_state_names[] = {
|
||||
|
||||
bool rc_runlevel_starting (void)
|
||||
{
|
||||
return (rc_is_dir (RC_SVCDIR "softscripts.old"));
|
||||
return (rc_is_dir (RC_SVCDIR "/softscripts.old"));
|
||||
}
|
||||
librc_hidden_def(rc_runlevel_starting)
|
||||
|
||||
bool rc_runlevel_stopping (void)
|
||||
{
|
||||
return (rc_is_dir (RC_SVCDIR "softscripts.new"));
|
||||
return (rc_is_dir (RC_SVCDIR "/softscripts.new"));
|
||||
}
|
||||
librc_hidden_def(rc_runlevel_stopping)
|
||||
|
||||
@ -142,7 +142,7 @@ char *rc_resolve_service (const char *service)
|
||||
return (rc_xstrdup (buffer));
|
||||
}
|
||||
|
||||
snprintf (buffer, sizeof (buffer), RC_INITDIR "%s", service);
|
||||
snprintf (buffer, sizeof (buffer), RC_INITDIR "/%s", service);
|
||||
return (strdup (buffer));
|
||||
}
|
||||
librc_hidden_def(rc_resolve_service)
|
||||
@ -639,32 +639,13 @@ void rc_schedule_clear (const char *service)
|
||||
}
|
||||
librc_hidden_def(rc_schedule_clear)
|
||||
|
||||
static time_t get_uptime(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct sysinfo info;
|
||||
|
||||
sysinfo (&info);
|
||||
return (time_t) info.uptime;
|
||||
#else
|
||||
struct timespec tp;
|
||||
|
||||
if (clock_gettime (CLOCK_MONOTONIC, &tp) == -1) {
|
||||
eerror ("clock_gettime: %s", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return tp.tv_sec;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool rc_wait_service (const char *service)
|
||||
{
|
||||
char *svc;
|
||||
char *base;
|
||||
char *fifo;
|
||||
struct timeval tv;
|
||||
time_t start = get_uptime ();
|
||||
struct timespec ts;
|
||||
int nloops = WAIT_MAX / WAIT_INTERVAL;
|
||||
bool retval = false;
|
||||
bool forever = false;
|
||||
|
||||
@ -680,26 +661,24 @@ bool rc_wait_service (const char *service)
|
||||
forever = true;
|
||||
free (svc);
|
||||
|
||||
while (true) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = WAIT_INTERVAL;
|
||||
|
||||
while (nloops) {
|
||||
if (! rc_exists (fifo)) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = WAIT_INTERVAL;
|
||||
if (select (0, 0, 0, 0, &tv) < 0) {
|
||||
if (nanosleep (&ts, NULL) == -1) {
|
||||
if (errno != EINTR) {
|
||||
eerror ("select: %s",strerror (errno));
|
||||
eerror ("nanosleep: %s", strerror (errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! forever) {
|
||||
time_t now = get_uptime();
|
||||
if (now - start > WAIT_MAX)
|
||||
break;
|
||||
}
|
||||
if (! forever)
|
||||
nloops --;
|
||||
}
|
||||
|
||||
free (fifo);
|
||||
@ -819,13 +798,13 @@ librc_hidden_def(rc_service_delete)
|
||||
|
||||
char **rc_services_scheduled_by (const char *service)
|
||||
{
|
||||
char **dirs = rc_ls_dir (NULL, RC_SVCDIR "scheduled", 0);
|
||||
char **dirs = rc_ls_dir (NULL, RC_SVCDIR "/scheduled", 0);
|
||||
char **list = NULL;
|
||||
char *dir;
|
||||
int i;
|
||||
|
||||
STRLIST_FOREACH (dirs, dir, i) {
|
||||
char *file = rc_strcatpaths (RC_SVCDIR "scheduled", dir, service,
|
||||
char *file = rc_strcatpaths (RC_SVCDIR, "scheduled", dir, service,
|
||||
(char *) NULL);
|
||||
if (rc_exists (file))
|
||||
list = rc_strlist_add (list, file);
|
||||
|
@ -8,7 +8,6 @@
|
||||
#ifndef _LIBRC_H_
|
||||
#define _LIBRC_H_
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -11,19 +11,19 @@
|
||||
# define LIB "lib"
|
||||
#endif
|
||||
|
||||
#define RC_LIBDIR "/" LIB "/rcscripts/"
|
||||
#define RC_SVCDIR RC_LIBDIR "init.d/"
|
||||
#define RC_DEPTREE RC_SVCDIR "deptree"
|
||||
#define RC_RUNLEVELDIR "/etc/runlevels/"
|
||||
#define RC_INITDIR "/etc/init.d/"
|
||||
#define RC_CONFDIR "/etc/conf.d/"
|
||||
#define RC_LIBDIR "/" LIB "/rcscripts"
|
||||
#define RC_SVCDIR RC_LIBDIR "/init.d"
|
||||
#define RC_DEPTREE RC_SVCDIR "/deptree"
|
||||
#define RC_RUNLEVELDIR "/etc/runlevels"
|
||||
#define RC_INITDIR "/etc/init.d"
|
||||
#define RC_CONFDIR "/etc/conf.d"
|
||||
|
||||
#define RC_SVCDIR_STARTING RC_SVCDIR "starting/"
|
||||
#define RC_SVCDIR_INACTIVE RC_SVCDIR "inactive/"
|
||||
#define RC_SVCDIR_STARTED RC_SVCDIR "started/"
|
||||
#define RC_SVCDIR_COLDPLUGGED RC_SVCDIR "coldplugged/"
|
||||
#define RC_SVCDIR_STARTING RC_SVCDIR "/starting"
|
||||
#define RC_SVCDIR_INACTIVE RC_SVCDIR "/inactive"
|
||||
#define RC_SVCDIR_STARTED RC_SVCDIR "/started"
|
||||
#define RC_SVCDIR_COLDPLUGGED RC_SVCDIR "/coldplugged"
|
||||
|
||||
#define RC_PLUGINDIR RC_LIBDIR "plugins/"
|
||||
#define RC_PLUGINDIR RC_LIBDIR "/plugins"
|
||||
|
||||
/* Max buffer to read a line from a file */
|
||||
#define RC_LINEBUFFER 4096
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -69,9 +70,9 @@ void rc_plugin_load (void)
|
||||
int (*fptr) (rc_hook_t, const char *);
|
||||
int len;
|
||||
|
||||
free (p);
|
||||
if (! h) {
|
||||
eerror ("dlopen: %s", dlerror ());
|
||||
free (p);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -99,7 +100,6 @@ void rc_plugin_load (void)
|
||||
}
|
||||
|
||||
free (func);
|
||||
free (p);
|
||||
}
|
||||
|
||||
rc_strlist_free (files);
|
||||
|
13
src/rc.c
13
src/rc.c
@ -37,17 +37,12 @@
|
||||
#include "rc-plugin.h"
|
||||
#include "strlist.h"
|
||||
|
||||
#define INITSH RC_LIBDIR "sh/init.sh"
|
||||
#define INITEARLYSH RC_LIBDIR "sh/init-early.sh"
|
||||
#define HALTSH RC_INITDIR "halt.sh"
|
||||
#define INITSH RC_LIBDIR "/sh/init.sh"
|
||||
#define INITEARLYSH RC_LIBDIR "/sh/init-early.sh"
|
||||
#define HALTSH RC_INITDIR "/halt.sh"
|
||||
#define SULOGIN "/sbin/sulogin"
|
||||
|
||||
#define RC_SVCDIR_STARTING RC_SVCDIR "starting/"
|
||||
#define RC_SVCDIR_INACTIVE RC_SVCDIR "inactive/"
|
||||
#define RC_SVCDIR_STARTED RC_SVCDIR "started/"
|
||||
#define RC_SVCDIR_COLDPLUGGED RC_SVCDIR "coldplugged/"
|
||||
|
||||
#define INTERACTIVE RC_SVCDIR "interactive"
|
||||
#define INTERACTIVE RC_SVCDIR "/interactive"
|
||||
|
||||
#define DEVBOOT "/dev/.rcboot"
|
||||
|
||||
|
1
src/rc.h
1
src/rc.h
@ -19,6 +19,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Special level names */
|
||||
#define RC_LEVEL_SYSINIT "sysinit"
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#define APPLET "runscript"
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
@ -81,8 +82,10 @@ static void setup_selinux (int argc, char **argv)
|
||||
return;
|
||||
}
|
||||
|
||||
selinux_run_init_old = (void (*)(void)) dlfunc (lib_handle, "selinux_runscript");
|
||||
selinux_run_init_new = (void (*)(int, char **)) dlfunc (lib_handle, "selinux_runscript2");
|
||||
selinux_run_init_old = (void (*)(void))
|
||||
dlfunc (lib_handle, "selinux_runscript");
|
||||
selinux_run_init_new = (void (*)(int, char **))
|
||||
dlfunc (lib_handle, "selinux_runscript2");
|
||||
|
||||
/* Use new run_init if it rc_exists, else fall back to old */
|
||||
if (selinux_run_init_new)
|
||||
@ -198,7 +201,7 @@ static bool in_control ()
|
||||
|
||||
static void uncoldplug ()
|
||||
{
|
||||
char *cold = rc_strcatpaths (RC_SVCDIR "coldplugged", applet, (char *) NULL);
|
||||
char *cold = rc_strcatpaths (RC_SVCDIR, "coldplugged", applet, (char *) NULL);
|
||||
if (rc_exists (cold) && unlink (cold) != 0)
|
||||
eerror ("%s: unlink `%s': %s", applet, cold, strerror (errno));
|
||||
free (cold);
|
||||
@ -368,16 +371,16 @@ static bool svc_exec (const char *arg1, const char *arg2)
|
||||
eerror ("fcntl: %s", strerror (errno));
|
||||
}
|
||||
|
||||
if (rc_exists (RC_SVCDIR "runscript.sh")) {
|
||||
execl (RC_SVCDIR "runscript.sh", service, service, arg1, arg2,
|
||||
if (rc_exists (RC_SVCDIR "/runscript.sh")) {
|
||||
execl (RC_SVCDIR "/runscript.sh", service, service, arg1, arg2,
|
||||
(char *) NULL);
|
||||
eerror ("%s: exec `" RC_SVCDIR "runscript.sh': %s",
|
||||
eerror ("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
|
||||
service, strerror (errno));
|
||||
_exit (EXIT_FAILURE);
|
||||
} else {
|
||||
execl (RC_LIBDIR "sh/runscript.sh", service, service, arg1, arg2,
|
||||
execl (RC_LIBDIR "/sh/runscript.sh", service, service, arg1, arg2,
|
||||
(char *) NULL);
|
||||
eerror ("%s: exec `" RC_LIBDIR "sh/runscript.sh': %s",
|
||||
eerror ("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
|
||||
service, strerror (errno));
|
||||
_exit (EXIT_FAILURE);
|
||||
}
|
||||
|
@ -9,8 +9,10 @@
|
||||
system so we can monitor daemons a little.
|
||||
*/
|
||||
|
||||
#define POLL_INTERVAL 20000
|
||||
#define START_WAIT 100000
|
||||
/* nano seconds */
|
||||
#define POLL_INTERVAL 20000000
|
||||
#define START_WAIT 100000000
|
||||
#define ONE_SECOND 1000000000
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -92,20 +94,6 @@ static void cleanup (void)
|
||||
rc_strlist_free (newenv);
|
||||
}
|
||||
|
||||
static int get_time(struct timeval *tp)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime (CLOCK_MONOTONIC, &ts) == -1) {
|
||||
eerror ("clock_gettime: %s", strerror (errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
tp->tv_sec = ts.tv_sec;
|
||||
tp->tv_usec = ts.tv_nsec / 1000;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int parse_signal (const char *sig)
|
||||
{
|
||||
typedef struct signalpair
|
||||
@ -347,9 +335,8 @@ static int run_stop_schedule (const char *exec, const char *cmd,
|
||||
int nkilled = 0;
|
||||
int tkilled = 0;
|
||||
int nrunning = 0;
|
||||
struct timeval tv;
|
||||
struct timeval now;
|
||||
struct timeval stopat;
|
||||
long nloops;
|
||||
struct timespec ts;
|
||||
|
||||
if (verbose) {
|
||||
if (pidfile)
|
||||
@ -390,30 +377,24 @@ static int run_stop_schedule (const char *exec, const char *cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_time (&stopat) != 0)
|
||||
return (0);
|
||||
nloops = (ONE_SECOND / POLL_INTERVAL) * item->value;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = POLL_INTERVAL;
|
||||
|
||||
stopat.tv_sec += item->value;
|
||||
while (1) {
|
||||
while (nloops) {
|
||||
if ((nrunning = do_stop (exec, cmd, pidfile,
|
||||
uid, 0, true, false, true)) == 0)
|
||||
return (true);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = POLL_INTERVAL;
|
||||
if (select (0, 0, 0, 0, &tv) < 0) {
|
||||
if (nanosleep (&ts, NULL) == -1) {
|
||||
if (errno == EINTR)
|
||||
eerror ("%s: caught an interupt", progname);
|
||||
else {
|
||||
eerror ("%s: select: %s", progname, strerror (errno));
|
||||
eerror ("%s: nanosleep: %s", progname, strerror (errno));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (get_time (&now) != 0)
|
||||
return (0);
|
||||
if (timercmp (&now, &stopat, >))
|
||||
break;
|
||||
nloops --;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -538,7 +519,6 @@ int start_stop_daemon (int argc, char **argv)
|
||||
int stdout_fd;
|
||||
int stderr_fd;
|
||||
pid_t pid;
|
||||
struct timeval tv;
|
||||
int i;
|
||||
char *svcname = getenv ("SVCNAME");
|
||||
char *env;
|
||||
@ -733,7 +713,7 @@ int start_stop_daemon (int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Validate that the binary rc_exists if we are starting */
|
||||
/* Validate that the binary exists if we are starting */
|
||||
if (exec && start) {
|
||||
char *tmp;
|
||||
if (ch_root)
|
||||
@ -893,14 +873,14 @@ int start_stop_daemon (int argc, char **argv)
|
||||
/* Clean the environment of any RC_ variables */
|
||||
STRLIST_FOREACH (environ, env, i)
|
||||
if (env && strncmp (env, "RC_", 3) != 0) {
|
||||
/* For the path character, remove the rcscript bin dir from it */
|
||||
if (strncmp (env, "PATH=" RC_LIBDIR "bin:",
|
||||
strlen ("PATH=" RC_LIBDIR "bin:")) == 0)
|
||||
/* For the path r, remove the rcscript bin dir from it */
|
||||
if (strncmp (env, "PATH=" RC_LIBDIR "/bin:",
|
||||
strlen ("PATH=" RC_LIBDIR "/bin:")) == 0)
|
||||
{
|
||||
char *path = env;
|
||||
char *newpath;
|
||||
int len;
|
||||
path += strlen ("PATH=" RC_LIBDIR "bin:");
|
||||
path += strlen ("PATH=" RC_LIBDIR "/bin:");
|
||||
len = sizeof (char *) * strlen (path) + 6;
|
||||
newpath = rc_xmalloc (len);
|
||||
snprintf (newpath, len, "PATH=%s", path);
|
||||
@ -974,24 +954,24 @@ int start_stop_daemon (int argc, char **argv)
|
||||
/* Wait a little bit and check that process is still running
|
||||
We do this as some badly written daemons fork and then barf */
|
||||
if (START_WAIT > 0) {
|
||||
struct timeval stopat;
|
||||
struct timeval now;
|
||||
struct timespec ts;
|
||||
int nloops = START_WAIT / POLL_INTERVAL;
|
||||
bool alive = false;
|
||||
bool retestpid = false;
|
||||
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = POLL_INTERVAL;
|
||||
|
||||
if (get_time (&stopat) != 0)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
stopat.tv_usec += START_WAIT;
|
||||
while (1) {
|
||||
bool alive = false;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = POLL_INTERVAL;
|
||||
if (select (0, 0, 0, 0, &tv) < 0) {
|
||||
/* Let our signal handler handle the interupt */
|
||||
if (errno != EINTR)
|
||||
eerrorx ("%s: select: %s", progname, strerror (errno));
|
||||
while (nloops) {
|
||||
if (nanosleep (&ts, NULL) == -1) {
|
||||
if (errno == EINTR)
|
||||
eerror ("%s: caught an interupt", progname);
|
||||
else {
|
||||
eerror ("%s: nanosleep: %s", progname, strerror (errno));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
nloops --;
|
||||
|
||||
/* This is knarly.
|
||||
If we backgrounded then we know the exact pid.
|
||||
@ -1023,11 +1003,6 @@ int start_stop_daemon (int argc, char **argv)
|
||||
|
||||
if (! alive)
|
||||
eerrorx ("%s: %s died", progname, exec);
|
||||
|
||||
if (get_time (&now) != 0)
|
||||
exit (EXIT_FAILURE);
|
||||
if (timercmp (&now, &stopat, >))
|
||||
break;
|
||||
}
|
||||
|
||||
if (retestpid) {
|
||||
|
Loading…
Reference in New Issue
Block a user