summaryrefslogtreecommitdiff
path: root/src/librc/librc-daemon.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-03-16 17:00:56 +0000
committerRoy Marples <roy@marples.name>2008-03-16 17:00:56 +0000
commitcb9da6a262b60255cd037f20b4cde3ab2c8a1e6a (patch)
treec5c57d5adedf009fdb02b53677e2cdf940bdb47c /src/librc/librc-daemon.c
parent40e12f6ba026af9c24d5c3d8e36512719ed5faee (diff)
downloadopenrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.gz
openrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.bz2
openrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.xz
Remove null terminated char ** lists in favour of RC_STRINGLIST, using TAILQ from queue(3). Refactor code style around the BSD KNF.
Diffstat (limited to 'src/librc/librc-daemon.c')
-rw-r--r--src/librc/librc-daemon.c438
1 files changed, 225 insertions, 213 deletions
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c
index ca23ed2..9ae4ac2 100644
--- a/src/librc/librc-daemon.c
+++ b/src/librc/librc-daemon.c
@@ -32,33 +32,33 @@
#include "librc.h"
#if defined(__linux__)
-static bool pid_is_cmd (pid_t pid, const char *cmd)
+static bool pid_is_cmd(pid_t pid, const char *cmd)
{
char buffer[32];
FILE *fp;
int c;
- snprintf(buffer, sizeof (buffer), "/proc/%d/stat", pid);
- if ((fp = fopen (buffer, "r")) == NULL)
- return (false);
+ snprintf(buffer, sizeof(buffer), "/proc/%d/stat", pid);
+ if ((fp = fopen(buffer, "r")) == NULL)
+ return false;
- while ((c = getc (fp)) != EOF && c != '(')
+ while ((c = getc(fp)) != EOF && c != '(')
;
if (c != '(') {
fclose(fp);
- return (false);
+ return false;
}
- while ((c = getc (fp)) != EOF && c == *cmd)
+ while ((c = getc(fp)) != EOF && c == *cmd)
cmd++;
- fclose (fp);
+ fclose(fp);
- return ((c == ')' && *cmd == '\0') ? true : false);
+ return (c == ')' && *cmd == '\0') ? true : false;
}
-static bool pid_is_exec (pid_t pid, const char *const *argv)
+static bool pid_is_exec(pid_t pid, const char *const *argv)
{
char cmdline[32];
char buffer[PATH_MAX];
@@ -66,31 +66,30 @@ static bool pid_is_exec (pid_t pid, const char *const *argv)
int fd = -1;
int r;
+ /* Check it's the right binary */
snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid);
memset (buffer, 0, sizeof (buffer));
-#if 0
- if (readlink (cmdline, buffer, sizeof (buffer)) != -1) {
- if (strcmp (exec, buffer) == 0)
- return (true);
+ if (readlink(cmdline, buffer, sizeof(buffer)) != -1) {
+ if (strcmp(*argv, buffer) == 0)
+ return true;
/* We should cater for deleted binaries too */
- if (strlen (buffer) > 10) {
- p = buffer + (strlen (buffer) - 10);
- if (strcmp (p, " (deleted)") == 0) {
+ if (strlen(buffer) > 10) {
+ p = buffer + (strlen(buffer) - 10);
+ if (strcmp(p, " (deleted)") == 0) {
*p = 0;
- if (strcmp (buffer, exec) == 0)
- return (true);
+ if (strcmp(buffer, *argv) == 0)
+ return true;
}
}
}
-#endif
- snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid);
- if ((fd = open (cmdline, O_RDONLY)) < 0)
- return (false);
+ snprintf(cmdline, sizeof(cmdline), "/proc/%u/cmdline", pid);
+ if ((fd = open(cmdline, O_RDONLY)) < 0)
+ return false;
- r = read (fd, buffer, sizeof (buffer));
- close (fd);
+ r = read(fd, buffer, sizeof(buffer));
+ close(fd);
if (r == -1)
return 0;
@@ -98,18 +97,18 @@ static bool pid_is_exec (pid_t pid, const char *const *argv)
buffer[r] = 0;
p = buffer;
while (*argv) {
- if (strcmp (*argv, p) != 0)
- return (false);
+ if (strcmp(*argv, p) != 0)
+ return false;
argv++;
- p += strlen (p) + 1;
+ p += strlen(p) + 1;
if ((unsigned) (p - buffer) > sizeof (buffer))
- return (false);
+ return false;
}
- return (true);
+ return true;
}
-pid_t *rc_find_pids (const char *const *argv, const char *cmd,
- uid_t uid, pid_t pid)
+pid_t *rc_find_pids(const char *const *argv, const char *cmd,
+ uid_t uid, pid_t pid)
{
DIR *procdir;
struct dirent *entry;
@@ -122,8 +121,8 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
pid_t runscript_pid = 0;
char *pp;
- if ((procdir = opendir ("/proc")) == NULL)
- return (NULL);
+ if ((procdir = opendir("/proc")) == NULL)
+ return NULL;
/*
We never match RC_RUNSCRIPT_PID if present so we avoid the below
@@ -136,13 +135,13 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
nasty
*/
- if ((pp = getenv ("RC_RUNSCRIPT_PID"))) {
- if (sscanf (pp, "%d", &runscript_pid) != 1)
+ if ((pp = getenv("RC_RUNSCRIPT_PID"))) {
+ if (sscanf(pp, "%d", &runscript_pid) != 1)
runscript_pid = 0;
}
- while ((entry = readdir (procdir)) != NULL) {
- if (sscanf (entry->d_name, "%d", &p) != 1)
+ while ((entry = readdir(procdir)) != NULL) {
+ if (sscanf(entry->d_name, "%d", &p) != 1)
continue;
if (runscript_pid != 0 && runscript_pid == p)
@@ -152,23 +151,23 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
continue;
if (uid) {
- snprintf (buffer, sizeof (buffer), "/proc/%d", p);
- if (stat (buffer, &sb) != 0 || sb.st_uid != uid)
+ snprintf(buffer, sizeof(buffer), "/proc/%d", p);
+ if (stat(buffer, &sb) != 0 || sb.st_uid != uid)
continue;
}
- if (cmd && ! pid_is_cmd (p, cmd))
+ if (cmd && ! pid_is_cmd(p, cmd))
continue;
- if (argv && ! cmd && ! pid_is_exec (p, (const char *const *)argv))
+ if (argv && ! cmd && ! pid_is_exec(p, (const char *const *)argv))
continue;
- tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
+ tmp = realloc(pids, sizeof (pid_t) * (npids + 2));
if (! tmp) {
- free (pids);
- closedir (procdir);
+ free(pids);
+ closedir(procdir);
errno = ENOMEM;
- return (NULL);
+ return NULL;
}
pids = tmp;
@@ -176,9 +175,9 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
pids[npids + 1] = 0;
npids++;
}
- closedir (procdir);
+ closedir(procdir);
- return (pids);
+ return pids;
}
librc_hidden_def(rc_find_pids)
@@ -206,8 +205,8 @@ librc_hidden_def(rc_find_pids)
# define _KVM_FLAGS O_RDONLY
# endif
-pid_t *rc_find_pids (const char *const *argv, const char *cmd,
- uid_t uid, pid_t pid)
+pid_t *rc_find_pids(const char *const *argv, const char *cmd,
+ uid_t uid, pid_t pid)
{
static kvm_t *kd = NULL;
char errbuf[_POSIX2_LINE_MAX];
@@ -218,44 +217,45 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
char **pargv;
pid_t *pids = NULL;
pid_t *tmp;
+ pid_t p;
const char *const *arg;
int npids = 0;
int match;
- if ((kd = kvm_openfiles (_KVM_PATH, _KVM_PATH,
- NULL, _KVM_FLAGS, errbuf)) == NULL)
+ if ((kd = kvm_openfiles(_KVM_PATH, _KVM_PATH,
+ NULL, _KVM_FLAGS, errbuf)) == NULL)
{
- fprintf (stderr, "kvm_open: %s\n", errbuf);
- return (NULL);
+ fprintf(stderr, "kvm_open: %s\n", errbuf);
+ return NULL;
}
#ifdef _KVM_GETPROC2
- kp = kvm_getproc2 (kd, KERN_PROC_ALL, 0, sizeof(*kp), &processes);
+ kp = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(*kp), &processes);
#else
- kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &processes);
+ kp = kvm_getprocs(kd, KERN_PROC_PROC, 0, &processes);
#endif
if ((kp == NULL && processes > 0) || (kp != NULL && processes < 0)) {
- fprintf (stderr, "kvm_getprocs: %s\n", kvm_geterr (kd));
- kvm_close (kd);
- return (NULL);
+ fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd));
+ kvm_close(kd);
+ return NULL;
}
for (i = 0; i < processes; i++) {
- pid_t p = _GET_KINFO_PID (kp[i]);
+ p = _GET_KINFO_PID(kp[i]);
if (pid != 0 && pid != p)
continue;
- if (uid != 0 && uid != _GET_KINFO_UID (kp[i]))
+ if (uid != 0 && uid != _GET_KINFO_UID(kp[i]))
continue;
if (cmd) {
- if (! _GET_KINFO_COMM (kp[i]) ||
- strcmp (cmd, _GET_KINFO_COMM (kp[i])) != 0)
+ if (! _GET_KINFO_COMM(kp[i]) ||
+ strcmp(cmd, _GET_KINFO_COMM(kp[i])) != 0)
continue;
}
if (argv && *argv && ! cmd) {
- pargv = _KVM_GETARGV (kd, &kp[i], pargc);
+ pargv = _KVM_GETARGV(kd, &kp[i], pargc);
if (! pargv || ! *pargv)
continue;
@@ -263,7 +263,7 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
match = 1;
while (*arg && *pargv)
- if (strcmp (*arg++, *pargv++) != 0) {
+ if (strcmp(*arg++, *pargv++) != 0) {
match = 0;
break;
}
@@ -272,12 +272,12 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
continue;
}
- tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
+ tmp = realloc(pids, sizeof(pid_t) * (npids + 2));
if (! tmp) {
- free (pids);
- kvm_close (kd);
+ free(pids);
+ kvm_close(kd);
errno = ENOMEM;
- return (NULL);
+ return NULL;
}
pids = tmp;
@@ -285,9 +285,9 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
pids[npids + 1] = 0;
npids++;
}
- kvm_close (kd);
+ kvm_close(kd);
- return (pids);
+ return pids;
}
librc_hidden_def(rc_find_pids)
@@ -295,67 +295,72 @@ librc_hidden_def(rc_find_pids)
# error "Platform not supported!"
#endif
-static bool _match_daemon (const char *path, const char *file, char **match)
+static bool _match_daemon(const char *path, const char *file,
+ RC_STRINGLIST *match)
{
char *line;
- char *ffile = rc_strcatpaths (path, file, (char *) NULL);
+ char *ffile = rc_strcatpaths(path, file, (char *) NULL);
FILE *fp;
+ RC_STRING *m;
- fp = fopen (ffile, "r");
- free (ffile);
+ fp = fopen(ffile, "r");
+ free(ffile);
if (! fp)
- return (false);
+ return false;
- while ((line = rc_getline (fp))) {
- rc_strlist_delete (&match, line);
- if (! match || !*match)
+ while ((line = rc_getline(fp))) {
+ TAILQ_FOREACH(m, match, entries)
+ if (strcmp(line, m->value) == 0) {
+ TAILQ_REMOVE(match, m, entries);
+ break;
+ }
+ if (! TAILQ_FIRST(match))
break;
}
- fclose (fp);
- if (match && *match)
- return (false);
- return (true);
+ fclose(fp);
+ if (TAILQ_FIRST(match))
+ return false;
+ return true;
}
-static char **_match_list (const char* const* argv,
- const char *name, const char *pidfile)
+static RC_STRINGLIST *_match_list(const char* const* argv,
+ const char *name, const char *pidfile)
{
- char **match = NULL;
+ RC_STRINGLIST *match = rc_stringlist_new();
int i = 0;
size_t l;
char *m;
while (argv && argv[i]) {
- l = strlen (*argv) + strlen ("argv_=") + 16;
- m = xmalloc (sizeof (char) * l);
- snprintf (m, l, "argv_0=%s", argv[i++]);
- rc_strlist_add (&match, m);
- free (m);
+ l = strlen(*argv) + strlen("argv_=") + 16;
+ m = xmalloc(sizeof(char) * l);
+ snprintf(m, l, "argv_0=%s", argv[i++]);
+ rc_stringlist_add(match, m);
+ free(m);
}
if (name) {
- l = strlen (name) + 6;
- m = xmalloc (sizeof (char) * l);
- snprintf (m, l, "name=%s", name);
- rc_strlist_add (&match, m);
- free (m);
+ l = strlen(name) + 6;
+ m = xmalloc(sizeof (char) * l);
+ snprintf(m, l, "name=%s", name);
+ rc_stringlist_add(match, m);
+ free(m);
}
if (pidfile) {
- l = strlen (pidfile) + 9;
- m = xmalloc (sizeof (char) * l);
- snprintf (m, l, "pidfile=%s", pidfile);
- rc_strlist_add (&match, m);
+ l = strlen(pidfile) + 9;
+ m = xmalloc(sizeof (char) * l);
+ snprintf(m, l, "pidfile=%s", pidfile);
+ rc_stringlist_add(match, m);
free (m);
}
- return (match);
+ return match;
}
-bool rc_service_daemon_set (const char *service, const char *const *argv,
- const char *name, const char *pidfile,
- bool started)
+bool rc_service_daemon_set(const char *service, const char *const *argv,
+ const char *name, const char *pidfile, bool started)
{
char *dirpath;
char *file = NULL;
@@ -364,123 +369,123 @@ bool rc_service_daemon_set (const char *service, const char *const *argv,
bool retval = false;
DIR *dp;
struct dirent *d;
- char **match = NULL;
+ RC_STRINGLIST *match;
int i = 0;
+ char buffer[10];
+ FILE *fp;
- if (! (argv && *argv) && ! name && ! pidfile) {
+ if (!(argv && *argv) && ! name && ! pidfile) {
errno = EINVAL;
- return (false);
+ return false;
}
- dirpath = rc_strcatpaths (RC_SVCDIR, "daemons",
- basename_c (service), (char *) NULL);
+ dirpath = rc_strcatpaths(RC_SVCDIR, "daemons",
+ basename_c(service), (char *) NULL);
- match = _match_list (argv, name, pidfile);
+ match = _match_list(argv, name, pidfile);
/* Regardless, erase any existing daemon info */
- if ((dp = opendir (dirpath))) {
- while ((d = readdir (dp))) {
+ if ((dp = opendir(dirpath))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- file = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
+ file = rc_strcatpaths(dirpath, d->d_name, (char *) NULL);
nfiles++;
if (! oldfile) {
- if (_match_daemon (dirpath, d->d_name, match)) {
+ if (_match_daemon(dirpath, d->d_name, match)) {
unlink (file);
oldfile = file;
nfiles--;
}
} else {
- rename (file, oldfile);
- free (oldfile);
+ rename(file, oldfile);
+ free(oldfile);
oldfile = file;
}
}
- free (file);
- closedir (dp);
+ free(file);
+ closedir(dp);
}
/* Now store our daemon info */
if (started) {
- char buffer[10];
- FILE *fp;
-
- if (mkdir (dirpath, 0755) == 0 || errno == EEXIST) {
- snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
- file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
- if ((fp = fopen (file, "w"))) {
+ if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
+ snprintf(buffer, sizeof(buffer), "%03d", nfiles + 1);
+ file = rc_strcatpaths(dirpath, buffer, (char *) NULL);
+ if ((fp = fopen(file, "w"))) {
while (argv && argv[i]) {
- fprintf (fp, "argv_%d=%s\n", i, argv[i]);
+ fprintf(fp, "argv_%d=%s\n", i, argv[i]);
i++;
}
- fprintf (fp, "name=");
+ fprintf(fp, "name=");
if (name)
- fprintf (fp, "%s", name);
- fprintf (fp, "\npidfile=");
+ fprintf(fp, "%s", name);
+ fprintf(fp, "\npidfile=");
if (pidfile)
- fprintf (fp, "%s", pidfile);
- fprintf (fp, "\n");
- fclose (fp);
+ fprintf(fp, "%s", pidfile);
+ fprintf(fp, "\n");
+ fclose(fp);
retval = true;
}
- free (file);
+ free(file);
}
} else
retval = true;
- rc_strlist_free (match);
- free (dirpath);
+ rc_stringlist_free(match);
+ free(dirpath);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_daemon_set)
-bool rc_service_started_daemon (const char *service, const char *const *argv,
- int indx)
+bool
+rc_service_started_daemon (const char *service, const char *const *argv,
+ int indx)
{
char *dirpath;
char *file;
size_t l;
- char **match;
+ RC_STRINGLIST *match;
bool retval = false;
DIR *dp;
struct dirent *d;
- if (! service || ! (argv && *argv))
- return (false);
+ if (!service || !(argv && *argv))
+ return false;
- dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename_c (service),
- (char *) NULL);
+ dirpath = rc_strcatpaths(RC_SVCDIR, "daemons", basename_c(service),
+ (char *) NULL);
- match = _match_list (argv, NULL, NULL);
+ match = _match_list(argv, NULL, NULL);
if (indx > 0) {
l = sizeof (char) * 10;
- file = xmalloc (l);
- snprintf (file, l, "%03d", indx);
- retval = _match_daemon (dirpath, file, match);
- free (file);
+ file = xmalloc(l);
+ snprintf(file, l, "%03d", indx);
+ retval = _match_daemon(dirpath, file, match);
+ free(file);
} else {
- if ((dp = opendir (dirpath))) {
- while ((d = readdir (dp))) {
+ if ((dp = opendir(dirpath))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- retval = _match_daemon (dirpath, d->d_name, match);
+ retval = _match_daemon(dirpath, d->d_name, match);
if (retval)
break;
}
- closedir (dp);
+ closedir(dp);
}
}
- free (dirpath);
- rc_strlist_free (match);
- return (retval);
+ free(dirpath);
+ rc_stringlist_free(match);
+ return retval;
}
librc_hidden_def(rc_service_started_daemon)
-bool rc_service_daemons_crashed (const char *service)
+bool rc_service_daemons_crashed(const char *service)
{
char *dirpath;
DIR *dp;
@@ -497,116 +502,123 @@ bool rc_service_daemons_crashed (const char *service)
char *p;
char *token;
bool retval = false;
+ RC_STRINGLIST *list;
+ RC_STRING *s;
+ size_t i;
- if (! service)
- return (false);
+ dirpath = rc_strcatpaths(RC_SVCDIR, "daemons", basename_c(service),
+ (char *) NULL);
- dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename_c (service),
- (char *) NULL);
-
- if (! (dp = opendir (dirpath))) {
- free (dirpath);
- return (false);
+ if (! (dp = opendir(dirpath))) {
+ free(dirpath);
+ return false;
}
- while ((d = readdir (dp))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- path = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
- fp = fopen (path, "r");
- free (path);
+ path = rc_strcatpaths(dirpath, d->d_name, (char *) NULL);
+ fp = fopen(path, "r");
+ free(path);
if (! fp)
break;
- while ((line = rc_getline (fp))) {
+ list = rc_stringlist_new();
+
+ while ((line = rc_getline(fp))) {
p = line;
- if ((token = strsep (&p, "=")) == NULL || ! p) {
- free (line);
+ if ((token = strsep(&p, "=")) == NULL || ! p) {
+ free(line);
continue;
}
- if (strlen (p) == 0) {
- free (line);
+ if (! *p) {
+ free(line);
continue;
}
- if (strncmp (token, "argv_", 5) == 0) {
- rc_strlist_add (&argv, p);
- } else if (strcmp (token, "exec") == 0) {
+ if (strncmp(token, "argv_", 5) == 0) {
+ rc_stringlist_add(list, p);
+ } else if (strcmp(token, "exec") == 0) {
if (exec)
- free (exec);
- exec = xstrdup (p);
- } else if (strcmp (token, "name") == 0) {
+ free(exec);
+ exec = xstrdup(p);
+ } else if (strcmp(token, "name") == 0) {
if (name)
- free (name);
- name = xstrdup (p);
- } else if (strcmp (token, "pidfile") == 0) {
+ free(name);
+ name = xstrdup(p);
+ } else if (strcmp(token, "pidfile") == 0) {
if (pidfile)
- free (pidfile);
- pidfile = xstrdup (p);
+ free(pidfile);
+ pidfile = xstrdup(p);
}
- free (line);
+ free(line);
}
- fclose (fp);
+ fclose(fp);
pid = 0;
if (pidfile) {
- if (! exists (pidfile)) {
+ if (! exists(pidfile)) {
retval = true;
break;
}
- if ((fp = fopen (pidfile, "r")) == NULL) {
+ if ((fp = fopen(pidfile, "r")) == NULL) {
retval = true;
break;
}
- if (fscanf (fp, "%d", &pid) != 1) {
+ if (fscanf(fp, "%d", &pid) != 1) {
fclose (fp);
retval = true;
break;
}
- fclose (fp);
- free (pidfile);
+ fclose(fp);
+ free(pidfile);
pidfile = NULL;
/* We have the pid, so no need to match on name */
- rc_strlist_free (argv);
- argv = NULL;
+ rc_stringlist_free(list);
+ list = NULL;
free (exec);
exec = NULL;
free (name);
name = NULL;
- }
-
- if (exec && ! argv) {
- rc_strlist_add (&argv, exec);
- free (exec);
+ } else {
+ if (exec && ! TAILQ_FIRST(list)) {
+ rc_stringlist_add(list, exec);
+ }
+ free(exec);
exec = NULL;
- }
- if ((pids = rc_find_pids ((const char *const *)argv, name, 0, pid)) == NULL) {
- retval = true;
- break;
+ /* We need to flatten our linked list into an array */
+ i = 0;
+ TAILQ_FOREACH(s, list, entries)
+ i++;
+ argv = xmalloc(sizeof(char *) * (i + 1));
+ i = 0;
+ TAILQ_FOREACH(s, list, entries)
+ argv[i++] = s->value;
+ argv[i] = '\0';
}
- free (pids);
- rc_strlist_free (argv);
+ if ((pids = rc_find_pids((const char *const *)argv, name, 0, pid)) == NULL)
+ retval = true;
+ free(pids);
+ free(argv);
argv = NULL;
- free (exec);
- exec = NULL;
- free (name);
+ rc_stringlist_free(list);
+ free(name);
name = NULL;
+ if (retval)
+ break;
}
- rc_strlist_free (argv);
- free (exec);
- free (name);
- free (dirpath);
- closedir (dp);
+ free(dirpath);
+ closedir(dp);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_daemons_crashed)