rc_find_pids now returns RC_PIDLIST instead of a NULL terminated array.
This commit is contained in:
parent
40930d7d0a
commit
50a7697bf2
@ -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
|
||||
|
@ -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,
|
||||
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,7 +200,7 @@ librc_hidden_def(rc_find_pids)
|
||||
# define _KVM_FLAGS O_RDONLY
|
||||
# endif
|
||||
|
||||
pid_t *rc_find_pids(const char *const *argv, const char *cmd,
|
||||
RC_PIDLIST *rc_find_pids(const char *const *argv, const char *cmd,
|
||||
uid_t uid, pid_t pid)
|
||||
{
|
||||
static kvm_t *kd = NULL;
|
||||
@ -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)
|
||||
retval = true;
|
||||
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(argv);
|
||||
argv = NULL;
|
||||
rc_stringlist_free(list);
|
||||
|
@ -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
|
||||
|
17
src/rc/rc.c
17
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;
|
||||
|
@ -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,21 +327,23 @@ 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;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (verbose)
|
||||
ebegin("Sending signal %d to PID %d", sig, pids[i]);
|
||||
ebegin("Sending signal %d to PID %d",
|
||||
sig, pi->pid);
|
||||
errno = 0;
|
||||
killed = (kill(pids[i], sig) == 0 || errno == ESRCH ? true : false);
|
||||
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, pids[i], strerror(errno));
|
||||
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 {
|
||||
@ -339,6 +351,8 @@ static int do_stop(const char *const *argv, const char *cmd,
|
||||
nkilled++;
|
||||
}
|
||||
}
|
||||
free(pi);
|
||||
}
|
||||
|
||||
free(pids);
|
||||
return nkilled;
|
||||
|
Loading…
Reference in New Issue
Block a user