diff options
| -rw-r--r-- | man/rc_find_pids.3 | 18 | ||||
| -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 | 
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); | 
