aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-03-17 09:59:52 +0000
committerRoy Marples <roy@marples.name>2008-03-17 09:59:52 +0000
commit50a7697bf207e4919ce893bfc1604fd3a9d807de (patch)
tree1a9c9debaa4d5d862f42c8015826d35b0ce26d7c
parent40930d7d0a613aaf6fa124a5963afcae0c30ce7a (diff)
rc_find_pids now returns RC_PIDLIST instead of a NULL terminated array.
-rw-r--r--man/rc_find_pids.318
-rw-r--r--src/librc/librc-daemon.c71
-rw-r--r--src/librc/rc.h9
-rw-r--r--src/rc/rc.c17
-rw-r--r--src/rc/start-stop-daemon.c50
5 files changed, 93 insertions, 72 deletions
diff --git a/man/rc_find_pids.3 b/man/rc_find_pids.3
index 5698e609..1d6aabea 100644
--- a/man/rc_find_pids.3
+++ b/man/rc_find_pids.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Mar 17, 2008
.Dt RC_FIND_PIDS 3 SMM
.Os OpenRC
.Sh NAME
@@ -32,20 +32,22 @@
Run Command library (librc, -lrc)
.Sh SYNOPSIS
.In rc.h
-.Ft "pid_t *" Fo rc_find_pids
-.Fa "const char *exec"
+.Ft "RC_PIDLIST *" Fo rc_find_pids
+.Fa "const char *const *argv"
.Fa "const char *cmd"
.Fa "uid_t uid"
.Fa "pid_t pid"
.Fc
.Sh DESCRIPTION
.Fn rc_find_pids
-returns a NULL terminated list of pids for processes matching the given
-criteria. If
+returns RC_PIDLIST, a structure based on the LIST macro from
+.Xr queue 3
+which contains all the pids found matching the given criteria.
+If
.Fa pid
is given then only that pid is returned if it is running. Otherise we check
all instances of
-.Fa exec
+.Fa argv
with a process name of
.Fa cmd
owned by
@@ -59,8 +61,10 @@ On BSD systems we use
and on Linux systems we use the
.Pa /proc
filesystem to find our processes.
+.Pp
+Each RC_PID should be freed in the list as well as the list itself when done.
.Sh SEE ALSO
.Xr free 3 ,
-.Xr malloc 3
+.Xr queue 3
.Sh AUTHORS
.An "Roy Marples" Aq roy@marples.name
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);