diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/librc/librc-daemon.c | 71 | ||||
-rw-r--r-- | src/librc/rc.h | 9 | ||||
-rw-r--r-- | src/rc/rc.c | 17 | ||||
-rw-r--r-- | src/rc/start-stop-daemon.c | 50 |
4 files changed, 82 insertions, 65 deletions
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c index 9ae4ac26..9e58c6a9 100644 --- a/src/librc/librc-daemon.c +++ b/src/librc/librc-daemon.c @@ -107,19 +107,18 @@ static bool pid_is_exec(pid_t pid, const char *const *argv) return true; } -pid_t *rc_find_pids(const char *const *argv, const char *cmd, - uid_t uid, pid_t pid) +RC_PIDLIST *rc_find_pids(const char *const *argv, const char *cmd, + uid_t uid, pid_t pid) { DIR *procdir; struct dirent *entry; - int npids = 0; pid_t p; - pid_t *pids = NULL; - pid_t *tmp = NULL; char buffer[PATH_MAX]; struct stat sb; pid_t runscript_pid = 0; char *pp; + RC_PIDLIST *pids = NULL; + RC_PID *pi; if ((procdir = opendir("/proc")) == NULL) return NULL; @@ -159,21 +158,17 @@ pid_t *rc_find_pids(const char *const *argv, const char *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)); - if (! tmp) { - free(pids); - closedir(procdir); - errno = ENOMEM; - return NULL; + if (! pids) { + pids = xmalloc(sizeof(*pids)); + LIST_INIT(pids); } - pids = tmp; - - pids[npids] = p; - pids[npids + 1] = 0; - npids++; + pi = xmalloc(sizeof(*pi)); + pi->pid = p; + LIST_INSERT_HEAD(pids, pi, entries); } closedir(procdir); @@ -205,8 +200,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) +RC_PIDLIST *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]; @@ -215,8 +210,8 @@ pid_t *rc_find_pids(const char *const *argv, const char *cmd, int processes = 0; int pargc = 0; char **pargv; - pid_t *pids = NULL; - pid_t *tmp; + RC_PIDLIST *pids = NULL; + RC_PID *pi; pid_t p; const char *const *arg; int npids = 0; @@ -272,18 +267,13 @@ pid_t *rc_find_pids(const char *const *argv, const char *cmd, continue; } - tmp = realloc(pids, sizeof(pid_t) * (npids + 2)); - if (! tmp) { - free(pids); - kvm_close(kd); - errno = ENOMEM; - return NULL; + if (! pids) { + pids = xmalloc(sizeof(*pids)); + LIST_INIT(pids); } - pids = tmp; - - pids[npids] = p; - pids[npids + 1] = 0; - npids++; + pi = xmalloc(sizeof(*pi)); + pi->pid = p; + LIST_INSERT_HEAD(pids, pi, entries); } kvm_close(kd); @@ -498,7 +488,9 @@ bool rc_service_daemons_crashed(const char *service) char *name = NULL; char *pidfile = NULL; pid_t pid = 0; - pid_t *pids = NULL; + RC_PIDLIST *pids; + RC_PID *p1; + RC_PID *p2; char *p; char *token; bool retval = false; @@ -604,9 +596,18 @@ bool rc_service_daemons_crashed(const char *service) argv[i] = '\0'; } - if ((pids = rc_find_pids((const char *const *)argv, name, 0, pid)) == NULL) + if ((pids = rc_find_pids((const char *const *)argv, + name, 0, pid)) == NULL) + { + p1 = LIST_FIRST(pids); + while (p1) { + p2 = LIST_NEXT(p1, entries); + free(p1); + p1 = p2; + } + free(pids); retval = true; - free(pids); + } free(argv); argv = NULL; rc_stringlist_free(list); diff --git a/src/librc/rc.h b/src/librc/rc.h index 061959e7..bf40e31c 100644 --- a/src/librc/rc.h +++ b/src/librc/rc.h @@ -451,6 +451,13 @@ void rc_stringlist_free(RC_STRINGLIST *); * @return pointer to the new path */ char *rc_strcatpaths(const char *, const char *, ...) SENTINEL; +typedef struct rc_pid +{ + pid_t pid; + LIST_ENTRY(rc_pid) entries; +} RC_PID; +typedef LIST_HEAD(rc_pidlist, rc_pid) RC_PIDLIST; + /*! Find processes based on criteria. * All of these are optional. * pid overrides anything else. @@ -460,6 +467,6 @@ char *rc_strcatpaths(const char *, const char *, ...) SENTINEL; * @param uid to check for * @param pid to check for * @return NULL terminated list of pids */ -pid_t *rc_find_pids(const char *const *, const char *, uid_t, pid_t); +RC_PIDLIST *rc_find_pids(const char *const *, const char *, uid_t, pid_t); #endif diff --git a/src/rc/rc.c b/src/rc/rc.c index 6754d2d3..d906870c 100644 --- a/src/rc/rc.c +++ b/src/rc/rc.c @@ -99,12 +99,7 @@ static RC_HOOK hook_out = 0; struct termios *termios_orig = NULL; -typedef struct piditem -{ - pid_t pid; - LIST_ENTRY(piditem) entries; -} PIDITEM; -LIST_HEAD(, piditem) service_pids; +RC_PIDLIST service_pids; static void clean_failed(void) { @@ -138,8 +133,8 @@ static void clean_failed(void) static void cleanup(void) { if (applet && strcmp(applet, "rc") == 0) { - PIDITEM *p1 = LIST_FIRST(&service_pids); - PIDITEM *p2; + RC_PID *p1 = LIST_FIRST(&service_pids); + RC_PID *p2; if (hook_out) rc_plugin_run(hook_out, runlevel); @@ -410,14 +405,14 @@ static int get_ksoftlevel(char *buffer, int buffer_len) static void add_pid(pid_t pid) { - PIDITEM *p = xmalloc(sizeof(*p)); + RC_PID *p = xmalloc(sizeof(*p)); p->pid = pid; LIST_INSERT_HEAD(&service_pids, p, entries); } static void remove_pid(pid_t pid) { - PIDITEM *p; + RC_PID *p; LIST_FOREACH(p, &service_pids, entries) if (p->pid == pid) { @@ -437,7 +432,7 @@ static void handle_signal(int sig) int serrno = errno; char signame[10] = { '\0' }; pid_t pid; - PIDITEM *pi; + RC_PID *pi; int status = 0; struct winsize ws; sigset_t sset; diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index bfb737a5..9b1c109e 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -73,6 +73,15 @@ static struct pam_conv conv = { NULL, NULL}; #include "rc.h" #include "rc-misc.h" +/* Some libc implementations don't define this */ +#ifndef LIST_FOREACH_SAFE +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + + typedef struct scheduleitem { enum @@ -301,11 +310,12 @@ static int do_stop(const char *const *argv, const char *cmd, const char *pidfile, uid_t uid,int sig, bool quiet, bool verbose, bool test) { - pid_t *pids; + RC_PIDLIST *pids; + RC_PID *pi; + RC_PID *np; bool killed; int nkilled = 0; pid_t pid = 0; - int i; if (pidfile) { if ((pid = get_pid(pidfile, quiet)) == -1) @@ -317,27 +327,31 @@ static int do_stop(const char *const *argv, const char *cmd, if (! pids) return 0; - for (i = 0; pids[i]; i++) { + LIST_FOREACH_SAFE(pi, pids, entries, np) { if (test) { if (! quiet) - einfo("Would send signal %d to PID %d", sig, pids[i]); + einfo("Would send signal %d to PID %d", + sig, pi->pid); nkilled++; - continue; - } - - if (verbose) - ebegin("Sending signal %d to PID %d", sig, pids[i]); - errno = 0; - killed = (kill(pids[i], sig) == 0 || errno == ESRCH ? true : false); - if (verbose) - eend(killed ? 0 : 1, "%s: failed to send signal %d to PID %d: %s", - applet, sig, pids[i], strerror(errno)); - if (! killed) { - nkilled = -1; } else { - if (nkilled != -1) - nkilled++; + if (verbose) + ebegin("Sending signal %d to PID %d", + sig, pi->pid); + errno = 0; + killed = (kill(pi->pid, sig) == 0 || + errno == ESRCH ? true : false); + if (verbose) + eend(killed ? 0 : 1, + "%s: failed to send signal %d to PID %d: %s", + applet, sig, pi->pid, strerror(errno)); + if (! killed) { + nkilled = -1; + } else { + if (nkilled != -1) + nkilled++; + } } + free(pi); } free(pids); |