rc_find_pids now returns RC_PIDLIST instead of a NULL terminated array.
This commit is contained in:
		| @@ -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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user