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