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
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd Feb 22, 2008
|
.Dd Mar 17, 2008
|
||||||
.Dt RC_FIND_PIDS 3 SMM
|
.Dt RC_FIND_PIDS 3 SMM
|
||||||
.Os OpenRC
|
.Os OpenRC
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -32,20 +32,22 @@
|
|||||||
Run Command library (librc, -lrc)
|
Run Command library (librc, -lrc)
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In rc.h
|
.In rc.h
|
||||||
.Ft "pid_t *" Fo rc_find_pids
|
.Ft "RC_PIDLIST *" Fo rc_find_pids
|
||||||
.Fa "const char *exec"
|
.Fa "const char *const *argv"
|
||||||
.Fa "const char *cmd"
|
.Fa "const char *cmd"
|
||||||
.Fa "uid_t uid"
|
.Fa "uid_t uid"
|
||||||
.Fa "pid_t pid"
|
.Fa "pid_t pid"
|
||||||
.Fc
|
.Fc
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Fn rc_find_pids
|
.Fn rc_find_pids
|
||||||
returns a NULL terminated list of pids for processes matching the given
|
returns RC_PIDLIST, a structure based on the LIST macro from
|
||||||
criteria. If
|
.Xr queue 3
|
||||||
|
which contains all the pids found matching the given criteria.
|
||||||
|
If
|
||||||
.Fa pid
|
.Fa pid
|
||||||
is given then only that pid is returned if it is running. Otherise we check
|
is given then only that pid is returned if it is running. Otherise we check
|
||||||
all instances of
|
all instances of
|
||||||
.Fa exec
|
.Fa argv
|
||||||
with a process name of
|
with a process name of
|
||||||
.Fa cmd
|
.Fa cmd
|
||||||
owned by
|
owned by
|
||||||
@ -59,8 +61,10 @@ On BSD systems we use
|
|||||||
and on Linux systems we use the
|
and on Linux systems we use the
|
||||||
.Pa /proc
|
.Pa /proc
|
||||||
filesystem to find our processes.
|
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
|
.Sh SEE ALSO
|
||||||
.Xr free 3 ,
|
.Xr free 3 ,
|
||||||
.Xr malloc 3
|
.Xr queue 3
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An "Roy Marples" Aq roy@marples.name
|
.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;
|
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)
|
uid_t uid, pid_t pid)
|
||||||
{
|
{
|
||||||
DIR *procdir;
|
DIR *procdir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
int npids = 0;
|
|
||||||
pid_t p;
|
pid_t p;
|
||||||
pid_t *pids = NULL;
|
|
||||||
pid_t *tmp = NULL;
|
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
pid_t runscript_pid = 0;
|
pid_t runscript_pid = 0;
|
||||||
char *pp;
|
char *pp;
|
||||||
|
RC_PIDLIST *pids = NULL;
|
||||||
|
RC_PID *pi;
|
||||||
|
|
||||||
if ((procdir = opendir("/proc")) == NULL)
|
if ((procdir = opendir("/proc")) == NULL)
|
||||||
return 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))
|
if (cmd && ! pid_is_cmd(p, cmd))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (argv && ! cmd && ! pid_is_exec(p, (const char *const *)argv))
|
if (argv && ! cmd && !
|
||||||
|
pid_is_exec(p, (const char *const *)argv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tmp = realloc(pids, sizeof (pid_t) * (npids + 2));
|
if (! pids) {
|
||||||
if (! tmp) {
|
pids = xmalloc(sizeof(*pids));
|
||||||
free(pids);
|
LIST_INIT(pids);
|
||||||
closedir(procdir);
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
pids = tmp;
|
pi = xmalloc(sizeof(*pi));
|
||||||
|
pi->pid = p;
|
||||||
pids[npids] = p;
|
LIST_INSERT_HEAD(pids, pi, entries);
|
||||||
pids[npids + 1] = 0;
|
|
||||||
npids++;
|
|
||||||
}
|
}
|
||||||
closedir(procdir);
|
closedir(procdir);
|
||||||
|
|
||||||
@ -205,8 +200,8 @@ librc_hidden_def(rc_find_pids)
|
|||||||
# define _KVM_FLAGS O_RDONLY
|
# define _KVM_FLAGS O_RDONLY
|
||||||
# endif
|
# 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)
|
uid_t uid, pid_t pid)
|
||||||
{
|
{
|
||||||
static kvm_t *kd = NULL;
|
static kvm_t *kd = NULL;
|
||||||
char errbuf[_POSIX2_LINE_MAX];
|
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 processes = 0;
|
||||||
int pargc = 0;
|
int pargc = 0;
|
||||||
char **pargv;
|
char **pargv;
|
||||||
pid_t *pids = NULL;
|
RC_PIDLIST *pids = NULL;
|
||||||
pid_t *tmp;
|
RC_PID *pi;
|
||||||
pid_t p;
|
pid_t p;
|
||||||
const char *const *arg;
|
const char *const *arg;
|
||||||
int npids = 0;
|
int npids = 0;
|
||||||
@ -272,18 +267,13 @@ pid_t *rc_find_pids(const char *const *argv, const char *cmd,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = realloc(pids, sizeof(pid_t) * (npids + 2));
|
if (! pids) {
|
||||||
if (! tmp) {
|
pids = xmalloc(sizeof(*pids));
|
||||||
free(pids);
|
LIST_INIT(pids);
|
||||||
kvm_close(kd);
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
pids = tmp;
|
pi = xmalloc(sizeof(*pi));
|
||||||
|
pi->pid = p;
|
||||||
pids[npids] = p;
|
LIST_INSERT_HEAD(pids, pi, entries);
|
||||||
pids[npids + 1] = 0;
|
|
||||||
npids++;
|
|
||||||
}
|
}
|
||||||
kvm_close(kd);
|
kvm_close(kd);
|
||||||
|
|
||||||
@ -498,7 +488,9 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *pidfile = NULL;
|
char *pidfile = NULL;
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
pid_t *pids = NULL;
|
RC_PIDLIST *pids;
|
||||||
|
RC_PID *p1;
|
||||||
|
RC_PID *p2;
|
||||||
char *p;
|
char *p;
|
||||||
char *token;
|
char *token;
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
@ -604,9 +596,18 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
argv[i] = '\0';
|
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;
|
retval = true;
|
||||||
free(pids);
|
}
|
||||||
free(argv);
|
free(argv);
|
||||||
argv = NULL;
|
argv = NULL;
|
||||||
rc_stringlist_free(list);
|
rc_stringlist_free(list);
|
||||||
|
@ -451,6 +451,13 @@ void rc_stringlist_free(RC_STRINGLIST *);
|
|||||||
* @return pointer to the new path */
|
* @return pointer to the new path */
|
||||||
char *rc_strcatpaths(const char *, const char *, ...) SENTINEL;
|
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.
|
/*! Find processes based on criteria.
|
||||||
* All of these are optional.
|
* All of these are optional.
|
||||||
* pid overrides anything else.
|
* pid overrides anything else.
|
||||||
@ -460,6 +467,6 @@ char *rc_strcatpaths(const char *, const char *, ...) SENTINEL;
|
|||||||
* @param uid to check for
|
* @param uid to check for
|
||||||
* @param pid to check for
|
* @param pid to check for
|
||||||
* @return NULL terminated list of pids */
|
* @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
|
#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;
|
struct termios *termios_orig = NULL;
|
||||||
|
|
||||||
typedef struct piditem
|
RC_PIDLIST service_pids;
|
||||||
{
|
|
||||||
pid_t pid;
|
|
||||||
LIST_ENTRY(piditem) entries;
|
|
||||||
} PIDITEM;
|
|
||||||
LIST_HEAD(, piditem) service_pids;
|
|
||||||
|
|
||||||
static void clean_failed(void)
|
static void clean_failed(void)
|
||||||
{
|
{
|
||||||
@ -138,8 +133,8 @@ static void clean_failed(void)
|
|||||||
static void cleanup(void)
|
static void cleanup(void)
|
||||||
{
|
{
|
||||||
if (applet && strcmp(applet, "rc") == 0) {
|
if (applet && strcmp(applet, "rc") == 0) {
|
||||||
PIDITEM *p1 = LIST_FIRST(&service_pids);
|
RC_PID *p1 = LIST_FIRST(&service_pids);
|
||||||
PIDITEM *p2;
|
RC_PID *p2;
|
||||||
|
|
||||||
if (hook_out)
|
if (hook_out)
|
||||||
rc_plugin_run(hook_out, runlevel);
|
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)
|
static void add_pid(pid_t pid)
|
||||||
{
|
{
|
||||||
PIDITEM *p = xmalloc(sizeof(*p));
|
RC_PID *p = xmalloc(sizeof(*p));
|
||||||
p->pid = pid;
|
p->pid = pid;
|
||||||
LIST_INSERT_HEAD(&service_pids, p, entries);
|
LIST_INSERT_HEAD(&service_pids, p, entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_pid(pid_t pid)
|
static void remove_pid(pid_t pid)
|
||||||
{
|
{
|
||||||
PIDITEM *p;
|
RC_PID *p;
|
||||||
|
|
||||||
LIST_FOREACH(p, &service_pids, entries)
|
LIST_FOREACH(p, &service_pids, entries)
|
||||||
if (p->pid == pid) {
|
if (p->pid == pid) {
|
||||||
@ -437,7 +432,7 @@ static void handle_signal(int sig)
|
|||||||
int serrno = errno;
|
int serrno = errno;
|
||||||
char signame[10] = { '\0' };
|
char signame[10] = { '\0' };
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
PIDITEM *pi;
|
RC_PID *pi;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
sigset_t sset;
|
sigset_t sset;
|
||||||
|
@ -73,6 +73,15 @@ static struct pam_conv conv = { NULL, NULL};
|
|||||||
#include "rc.h"
|
#include "rc.h"
|
||||||
#include "rc-misc.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
|
typedef struct scheduleitem
|
||||||
{
|
{
|
||||||
enum
|
enum
|
||||||
@ -301,11 +310,12 @@ static int do_stop(const char *const *argv, const char *cmd,
|
|||||||
const char *pidfile, uid_t uid,int sig,
|
const char *pidfile, uid_t uid,int sig,
|
||||||
bool quiet, bool verbose, bool test)
|
bool quiet, bool verbose, bool test)
|
||||||
{
|
{
|
||||||
pid_t *pids;
|
RC_PIDLIST *pids;
|
||||||
|
RC_PID *pi;
|
||||||
|
RC_PID *np;
|
||||||
bool killed;
|
bool killed;
|
||||||
int nkilled = 0;
|
int nkilled = 0;
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (pidfile) {
|
if (pidfile) {
|
||||||
if ((pid = get_pid(pidfile, quiet)) == -1)
|
if ((pid = get_pid(pidfile, quiet)) == -1)
|
||||||
@ -317,27 +327,31 @@ static int do_stop(const char *const *argv, const char *cmd,
|
|||||||
if (! pids)
|
if (! pids)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; pids[i]; i++) {
|
LIST_FOREACH_SAFE(pi, pids, entries, np) {
|
||||||
if (test) {
|
if (test) {
|
||||||
if (! quiet)
|
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++;
|
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 {
|
} else {
|
||||||
if (nkilled != -1)
|
if (verbose)
|
||||||
nkilled++;
|
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);
|
free(pids);
|
||||||
|
Loading…
Reference in New Issue
Block a user