aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2007-08-09 14:33:20 +0000
committerRoy Marples <roy@marples.name>2007-08-09 14:33:20 +0000
commit0084bc41ef5db968cac0f64ae9d0b31dc7621818 (patch)
treeda0ca3238b1d548211cef40c073f897ce3c3bcc4
parent9072ce748ff67e74756adf6883dfb4b12894d9b8 (diff)
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.
-rw-r--r--src/Makefile1
-rw-r--r--src/librc-depend.c22
-rw-r--r--src/librc-misc.c45
-rw-r--r--src/librc.c59
-rw-r--r--src/librc.h1
-rw-r--r--src/rc-misc.h26
-rw-r--r--src/rc-plugin.c4
-rw-r--r--src/rc.c13
-rw-r--r--src/rc.h1
-rw-r--r--src/runscript.c19
-rw-r--r--src/start-stop-daemon.c93
11 files changed, 119 insertions, 165 deletions
diff --git a/src/Makefile b/src/Makefile
index 5c50cfd4..dc6d86f5 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -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
diff --git a/src/librc-depend.c b/src/librc-depend.c
index c8dfd02a..b51fc3cb 100644
--- a/src/librc-depend.c
+++ b/src/librc-depend.c
@@ -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
};
diff --git a/src/librc-misc.c b/src/librc-misc.c
index b52c2507..2aee5d43 100644
--- a/src/librc-misc.c
+++ b/src/librc-misc.c
@@ -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;
+ length = strlen (path1) + strlen (paths) + 1;
+ if (*paths != '/')
+ length ++;
+
va_start (ap, paths);
- while ((p = va_arg (ap, char *)) != NULL)
- length += strlen (p) + 1;
+ while ((p = va_arg (ap, char *)) != NULL) {
+ if (*p != '/')
+ length ++;
+ length += strlen (p);
+ }
va_end (ap);
- path = rc_xmalloc (length);
+ pathp = path = rc_xmalloc (length * sizeof (char *));
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);
+ 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 (*pathp != '/')
- *pathp++ = '/';
+ 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);
diff --git a/src/librc.c b/src/librc.c
index 5b815720..9b48b6bb 100644
--- a/src/librc.c
+++ b/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);
diff --git a/src/librc.h b/src/librc.h
index ec126aba..6118f48b 100644
--- a/src/librc.h
+++ b/src/librc.h
@@ -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>
diff --git a/src/rc-misc.h b/src/rc-misc.h
index 20dc74f7..6ffc868f 100644
--- a/src/rc-misc.h
+++ b/src/rc-misc.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_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_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_PLUGINDIR RC_LIBDIR "/plugins"
/* Max buffer to read a line from a file */
#define RC_LINEBUFFER 4096
diff --git a/src/rc-plugin.c b/src/rc-plugin.c
index d8db975a..1103e469 100644
--- a/src/rc-plugin.c
+++ b/src/rc-plugin.c
@@ -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);
diff --git a/src/rc.c b/src/rc.c
index f7c4f98a..c8bbb2e9 100644
--- a/src/rc.c
+++ b/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"
diff --git a/src/rc.h b/src/rc.h
index 9920901c..829f8b95 100644
--- a/src/rc.h
+++ b/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"
diff --git a/src/runscript.c b/src/runscript.c
index 14d3c7bf..20e7561d 100644
--- a/src/runscript.c
+++ b/src/runscript.c
@@ -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);
}
diff --git a/src/start-stop-daemon.c b/src/start-stop-daemon.c
index 05325dfb..ddf55e25 100644
--- a/src/start-stop-daemon.c
+++ b/src/start-stop-daemon.c
@@ -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;
-
- 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));
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = POLL_INTERVAL;
+
+ 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) {