xref: /illumos-gate/usr/src/cmd/priocntl/priocntl.c (revision e0a59e987c88dc1f6ff89d2a31408275b8f723ae)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include	<stdio.h>
327c478bd9Sstevel@tonic-gate #include	<stdlib.h>
337c478bd9Sstevel@tonic-gate #include	<string.h>
347c478bd9Sstevel@tonic-gate #include	<wait.h>
357c478bd9Sstevel@tonic-gate #include	<search.h>
367c478bd9Sstevel@tonic-gate #include	<unistd.h>
377c478bd9Sstevel@tonic-gate #include	<sys/types.h>
387c478bd9Sstevel@tonic-gate #include	<dirent.h>
397c478bd9Sstevel@tonic-gate #include	<fcntl.h>
407c478bd9Sstevel@tonic-gate #include	<sys/param.h>
417c478bd9Sstevel@tonic-gate #include	<sys/procset.h>
427c478bd9Sstevel@tonic-gate #include	<sys/priocntl.h>
437c478bd9Sstevel@tonic-gate #include	<procfs.h>
447c478bd9Sstevel@tonic-gate #include	<macros.h>
457c478bd9Sstevel@tonic-gate #include	<libgen.h>
467c478bd9Sstevel@tonic-gate #include	<limits.h>
477c478bd9Sstevel@tonic-gate #include	<errno.h>
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #include	"priocntl.h"
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate  * This file contains the code implementing the class independent part
537c478bd9Sstevel@tonic-gate  * of the priocntl command.  Most of the useful work for the priocntl
547c478bd9Sstevel@tonic-gate  * command is done by the class specific sub-commands, the code for
557c478bd9Sstevel@tonic-gate  * which is elsewhere.  The class independent part of the command is
567c478bd9Sstevel@tonic-gate  * responsible for executing the appropriate class specific sub-commands
577c478bd9Sstevel@tonic-gate  * and providing any necessary input to the sub-commands.
587c478bd9Sstevel@tonic-gate  * Code in this file should never assume any knowledge of any specific
597c478bd9Sstevel@tonic-gate  * scheduler class (other than the SYS class).
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate #define	CLASSPATH	"/usr/lib/class"
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate typedef struct classpids {
657c478bd9Sstevel@tonic-gate 	char	clp_clname[PC_CLNMSZ];
667c478bd9Sstevel@tonic-gate 	pid_t	*clp_pidlist;
677c478bd9Sstevel@tonic-gate 	int	clp_pidlistsz;
687c478bd9Sstevel@tonic-gate 	int	clp_npids;
697c478bd9Sstevel@tonic-gate } classpids_t;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate static char usage[] =
727c478bd9Sstevel@tonic-gate "usage:	priocntl -l\n\
737c478bd9Sstevel@tonic-gate 	priocntl -d [-i idtype] [idlist]\n\
747c478bd9Sstevel@tonic-gate 	priocntl -s [-c class] [c.s.o.] [-i idtype] [idlist]\n\
757c478bd9Sstevel@tonic-gate 	priocntl -e [-c class] [c.s.o.] command [argument(s)]\n";
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate static char	basenm[BASENMSZ];
787c478bd9Sstevel@tonic-gate static char	cmdpath[MAXPATHLEN];
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate static char	*procdir = "/proc";
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate static int	print_classlist(void);
837c478bd9Sstevel@tonic-gate static void	set_procs(char *, idtype_t, int, char **, char **);
847c478bd9Sstevel@tonic-gate static void	exec_cmd(char *, char **);
857c478bd9Sstevel@tonic-gate static int	print_procs(idtype_t, int, char *[]);
867c478bd9Sstevel@tonic-gate static void	ids2pids(idtype_t, id_t *, int, classpids_t *, int);
877c478bd9Sstevel@tonic-gate static void	add_pid_tolist(classpids_t *, int, char *, pid_t);
887c478bd9Sstevel@tonic-gate static void	increase_pidlist(classpids_t *);
897c478bd9Sstevel@tonic-gate static boolean_t	idmatch(char *, char *, int, char **);
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate /*
927c478bd9Sstevel@tonic-gate  * These variables are defined to be used in prio_getopt() below.
937c478bd9Sstevel@tonic-gate  */
947c478bd9Sstevel@tonic-gate static	int	prio_getopt();
957c478bd9Sstevel@tonic-gate /* LINTED static unused */
967c478bd9Sstevel@tonic-gate static	int	prio_optopt = 0;
977c478bd9Sstevel@tonic-gate static	char	*prio_optarg = 0;
987c478bd9Sstevel@tonic-gate static	int	prio_optind = 1;
997c478bd9Sstevel@tonic-gate static	int	prio_sp = 1;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])1027c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1037c478bd9Sstevel@tonic-gate {
1047c478bd9Sstevel@tonic-gate 	int		c;
1057c478bd9Sstevel@tonic-gate 	int		lflag, dflag, sflag, eflag, cflag, iflag, csoptsflag;
1067c478bd9Sstevel@tonic-gate 	char		*clname;
1077c478bd9Sstevel@tonic-gate 	char		*idtypnm;
1087c478bd9Sstevel@tonic-gate 	idtype_t	idtype;
1097c478bd9Sstevel@tonic-gate 	int		idargc;
1107c478bd9Sstevel@tonic-gate 	char		**idargv;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	(void) strlcpy(cmdpath, argv[0], MAXPATHLEN);
1137c478bd9Sstevel@tonic-gate 	(void) strlcpy(basenm, basename(argv[0]), BASENMSZ);
1147c478bd9Sstevel@tonic-gate 	lflag = dflag = sflag = eflag = cflag = iflag = csoptsflag = 0;
1157c478bd9Sstevel@tonic-gate 	while ((c = prio_getopt(argc, argv, "ldsec:i:")) != -1) {
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 		switch (c) {
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 		case 'l':
1207c478bd9Sstevel@tonic-gate 			lflag++;
1217c478bd9Sstevel@tonic-gate 			break;
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 		case 'd':
1247c478bd9Sstevel@tonic-gate 			dflag++;
1257c478bd9Sstevel@tonic-gate 			break;
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 		case 's':
1287c478bd9Sstevel@tonic-gate 			sflag++;
1297c478bd9Sstevel@tonic-gate 			break;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 		case 'e':
1327c478bd9Sstevel@tonic-gate 			eflag++;
1337c478bd9Sstevel@tonic-gate 			break;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 		case 'c':
1367c478bd9Sstevel@tonic-gate 			cflag++;
1377c478bd9Sstevel@tonic-gate 			clname = prio_optarg;
1387c478bd9Sstevel@tonic-gate 			break;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 		case 'i':
1417c478bd9Sstevel@tonic-gate 			iflag++;
1427c478bd9Sstevel@tonic-gate 			idtypnm = prio_optarg;
1437c478bd9Sstevel@tonic-gate 			break;
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 		case '?':
1467c478bd9Sstevel@tonic-gate 			if (strcmp(argv[prio_optind - 1], "-c") == 0 ||
1477c478bd9Sstevel@tonic-gate 			    strcmp(argv[prio_optind - 1], "-i") == 0) {
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 				/*
1507c478bd9Sstevel@tonic-gate 				 * getopt() will return ? if either
1517c478bd9Sstevel@tonic-gate 				 * of these appear without an argument.
1527c478bd9Sstevel@tonic-gate 				 */
1537c478bd9Sstevel@tonic-gate 				fatalerr(usage);
1547c478bd9Sstevel@tonic-gate 			}
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 			/*
1577c478bd9Sstevel@tonic-gate 			 * We assume for now that any option that
1587c478bd9Sstevel@tonic-gate 			 * getopt() doesn't recognize (with the
1597c478bd9Sstevel@tonic-gate 			 * exception of c and i) is intended for a
1607c478bd9Sstevel@tonic-gate 			 * class specific subcommand.  For now we also
1617c478bd9Sstevel@tonic-gate 			 * require that all class specific options
1627c478bd9Sstevel@tonic-gate 			 * take an argument (until we can get smarter
1637c478bd9Sstevel@tonic-gate 			 * about parsing our options).
1647c478bd9Sstevel@tonic-gate 			 */
1657c478bd9Sstevel@tonic-gate 			csoptsflag++;
1667c478bd9Sstevel@tonic-gate 			prio_optind++;
1677c478bd9Sstevel@tonic-gate 			prio_sp = 1;
1687c478bd9Sstevel@tonic-gate 			break;
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 		default:
1717c478bd9Sstevel@tonic-gate 			break;
1727c478bd9Sstevel@tonic-gate 		}
1737c478bd9Sstevel@tonic-gate 	}
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	if (lflag) {
1767c478bd9Sstevel@tonic-gate 		if (dflag || sflag || eflag || cflag || iflag || csoptsflag)
1777c478bd9Sstevel@tonic-gate 			fatalerr(usage);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 		return (print_classlist());
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	} else if (dflag) {
1827c478bd9Sstevel@tonic-gate 		if (lflag || sflag || eflag || cflag || csoptsflag)
1837c478bd9Sstevel@tonic-gate 			fatalerr(usage);
1847c478bd9Sstevel@tonic-gate 		if (iflag) {
1857c478bd9Sstevel@tonic-gate 			if (str2idtyp(idtypnm, &idtype) == -1)
1867c478bd9Sstevel@tonic-gate 				fatalerr("%s: bad idtype %s\n", cmdpath,
1877c478bd9Sstevel@tonic-gate 				    idtypnm);
1887c478bd9Sstevel@tonic-gate 		} else {
1897c478bd9Sstevel@tonic-gate 			idtype = P_PID;
1907c478bd9Sstevel@tonic-gate 		}
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 		if (prio_optind < argc) {
1937c478bd9Sstevel@tonic-gate 			idargc = argc - prio_optind;
1947c478bd9Sstevel@tonic-gate 			idargv = &argv[prio_optind];
1957c478bd9Sstevel@tonic-gate 		} else {
1967c478bd9Sstevel@tonic-gate 			idargc = 0;
1977c478bd9Sstevel@tonic-gate 		}
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 		return (print_procs(idtype, idargc, idargv));
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	} else if (sflag) {
2027c478bd9Sstevel@tonic-gate 		if (lflag || dflag || eflag)
2037c478bd9Sstevel@tonic-gate 			fatalerr(usage);
2047c478bd9Sstevel@tonic-gate 		if (iflag) {
2057c478bd9Sstevel@tonic-gate 			if (str2idtyp(idtypnm, &idtype) == -1)
2067c478bd9Sstevel@tonic-gate 				fatalerr("%s: bad idtype %s\n", cmdpath,
2077c478bd9Sstevel@tonic-gate 				    idtypnm);
2087c478bd9Sstevel@tonic-gate 		} else {
2097c478bd9Sstevel@tonic-gate 			idtype = P_PID;
2107c478bd9Sstevel@tonic-gate 		}
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		if (cflag == 0)
2137c478bd9Sstevel@tonic-gate 			clname = NULL;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 		if (prio_optind < argc) {
2167c478bd9Sstevel@tonic-gate 			idargc = argc - prio_optind;
2177c478bd9Sstevel@tonic-gate 			idargv = &argv[prio_optind];
2187c478bd9Sstevel@tonic-gate 		} else {
2197c478bd9Sstevel@tonic-gate 			idargc = 0;
2207c478bd9Sstevel@tonic-gate 		}
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 		set_procs(clname, idtype, idargc, idargv, argv);
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	} else if (eflag) {
2257c478bd9Sstevel@tonic-gate 		if (lflag || dflag || sflag || iflag)
2267c478bd9Sstevel@tonic-gate 			fatalerr(usage);
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 		if (cflag == 0)
2297c478bd9Sstevel@tonic-gate 			clname = NULL;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 		if (prio_optind >= argc)
2327c478bd9Sstevel@tonic-gate 			fatalerr(usage);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 		exec_cmd(clname, argv);
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	} else {
2377c478bd9Sstevel@tonic-gate 		fatalerr(usage);
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	return (0);
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate /*
2457c478bd9Sstevel@tonic-gate  * Print the heading for the class list and execute the class
2467c478bd9Sstevel@tonic-gate  * specific sub-command with the -l option for each configured class.
2477c478bd9Sstevel@tonic-gate  */
2487c478bd9Sstevel@tonic-gate static int
print_classlist(void)2497c478bd9Sstevel@tonic-gate print_classlist(void)
2507c478bd9Sstevel@tonic-gate {
2517c478bd9Sstevel@tonic-gate 	id_t		cid;
2527c478bd9Sstevel@tonic-gate 	int		nclass;
2537c478bd9Sstevel@tonic-gate 	pcinfo_t	pcinfo;
2547c478bd9Sstevel@tonic-gate 	static char	subcmdpath[128];
2557c478bd9Sstevel@tonic-gate 	int		status;
2567c478bd9Sstevel@tonic-gate 	pid_t		pid;
2577c478bd9Sstevel@tonic-gate 	int		error = 0;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	/*
2607c478bd9Sstevel@tonic-gate 	 * No special privileges required for this operation.
2617c478bd9Sstevel@tonic-gate 	 * Set the effective UID back to the real UID.
2627c478bd9Sstevel@tonic-gate 	 */
2637c478bd9Sstevel@tonic-gate 	if (setuid(getuid()) == -1)
2647c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't set effective UID back to real UID\n",
2657c478bd9Sstevel@tonic-gate 		    cmdpath);
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	if ((nclass = priocntl(0, 0, PC_GETCLINFO, NULL)) == -1)
2687c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't get number of configured classes, priocntl"
2697c478bd9Sstevel@tonic-gate 		    " system call failed with errno %d\n", cmdpath, errno);
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	(void) printf("CONFIGURED CLASSES\n==================\n\n");
2727c478bd9Sstevel@tonic-gate 	(void) printf("SYS (System Class)\n");
2737c478bd9Sstevel@tonic-gate 	for (cid = 1; cid < nclass; cid++) {
2747c478bd9Sstevel@tonic-gate 		(void) printf("\n");
2757c478bd9Sstevel@tonic-gate 		(void) fflush(stdout);
2767c478bd9Sstevel@tonic-gate 		pcinfo.pc_cid = cid;
2777c478bd9Sstevel@tonic-gate 		if (priocntl(0, 0, PC_GETCLINFO, (caddr_t)&pcinfo) == -1)
2787c478bd9Sstevel@tonic-gate 			fatalerr("%s: can't get class name (class ID = %ld)\n",
2797c478bd9Sstevel@tonic-gate 			    cmdpath, cid);
2807c478bd9Sstevel@tonic-gate 		if (snprintf(subcmdpath, sizeof (subcmdpath), "%s/%s/%s%s",
2817c478bd9Sstevel@tonic-gate 		    CLASSPATH, pcinfo.pc_clname, pcinfo.pc_clname, basenm) >=
2827c478bd9Sstevel@tonic-gate 		    sizeof (subcmdpath))
2837c478bd9Sstevel@tonic-gate 			fatalerr("%s: can't generate %s specific subcommand\n",
2847c478bd9Sstevel@tonic-gate 			    cmdpath, pcinfo.pc_clname);
2857c478bd9Sstevel@tonic-gate 		if ((pid = fork()) == 0) {
2867c478bd9Sstevel@tonic-gate 			(void) execl(subcmdpath, subcmdpath, "-l", (char *)0);
2877c478bd9Sstevel@tonic-gate 			(void) printf("%s\n", pcinfo.pc_clname);
2887c478bd9Sstevel@tonic-gate 			fatalerr("\tCan't execute %s specific subcommand\n",
2897c478bd9Sstevel@tonic-gate 			    pcinfo.pc_clname);
2907c478bd9Sstevel@tonic-gate 		} else if (pid == (pid_t)-1) {
2917c478bd9Sstevel@tonic-gate 			(void) printf("%s\n", pcinfo.pc_clname);
2927c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
2937c478bd9Sstevel@tonic-gate 			    "Can't execute %s specific subcommand)\n",
2947c478bd9Sstevel@tonic-gate 			    pcinfo.pc_clname);
2957c478bd9Sstevel@tonic-gate 			error = 1;
2967c478bd9Sstevel@tonic-gate 		} else {
2977c478bd9Sstevel@tonic-gate 			(void) wait(&status);
2987c478bd9Sstevel@tonic-gate 			if (status)
2997c478bd9Sstevel@tonic-gate 				error = 1;
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	return (error);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate /*
3087c478bd9Sstevel@tonic-gate  * For each class represented within the set of processes specified by
3097c478bd9Sstevel@tonic-gate  * idtype/idargv, print_procs() executes the class specific sub-command
3107c478bd9Sstevel@tonic-gate  * with the -d option.  We pipe to each sub-command a list of pids in
3117c478bd9Sstevel@tonic-gate  * the set belonging to that class.
3127c478bd9Sstevel@tonic-gate  */
3137c478bd9Sstevel@tonic-gate static int
print_procs(idtype_t idtype,int idargc,char * idargv[])3147c478bd9Sstevel@tonic-gate print_procs(idtype_t idtype, int idargc, char *idargv[])
3157c478bd9Sstevel@tonic-gate {
3167c478bd9Sstevel@tonic-gate 	int		i;
3177c478bd9Sstevel@tonic-gate 	id_t		id;
3187c478bd9Sstevel@tonic-gate 	id_t		idlist[NIDS];
3197c478bd9Sstevel@tonic-gate 	int		nids;
3207c478bd9Sstevel@tonic-gate 	classpids_t	*clpids;
3217c478bd9Sstevel@tonic-gate 	int		nclass;
3227c478bd9Sstevel@tonic-gate 	id_t		cid;
3237c478bd9Sstevel@tonic-gate 	pcinfo_t	pcinfo;
3247c478bd9Sstevel@tonic-gate 	int		pidexists;
3257c478bd9Sstevel@tonic-gate 	FILE		*pipe_to_subcmd;
3267c478bd9Sstevel@tonic-gate 	char		subcmd[128];
3277c478bd9Sstevel@tonic-gate 	int		error = 0;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	/*
3317c478bd9Sstevel@tonic-gate 	 * Build a list of ids eliminating any duplicates in idargv.
3327c478bd9Sstevel@tonic-gate 	 */
3337c478bd9Sstevel@tonic-gate 	if (idtype == P_ALL) {
3347c478bd9Sstevel@tonic-gate 		/*
3357c478bd9Sstevel@tonic-gate 		 * No idlist should be specified. If one is specified,
3367c478bd9Sstevel@tonic-gate 		 * it is ignored.
3377c478bd9Sstevel@tonic-gate 		 */
3387c478bd9Sstevel@tonic-gate 		nids = 0;
3397c478bd9Sstevel@tonic-gate 	} else if (idargc == 0) {
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 		/*
3427c478bd9Sstevel@tonic-gate 		 * No ids supplied by user; use current id.
3437c478bd9Sstevel@tonic-gate 		 */
3447c478bd9Sstevel@tonic-gate 		if (getmyid(idtype, &idlist[0]) == -1)
3457c478bd9Sstevel@tonic-gate 			fatalerr("%s: Can't get ID for current process,"
3467c478bd9Sstevel@tonic-gate 			    " idtype = %d\n", cmdpath, idtype);
3477c478bd9Sstevel@tonic-gate 		nids = 1;
3487c478bd9Sstevel@tonic-gate 	} else {
3497c478bd9Sstevel@tonic-gate 		nids = 0;
3507c478bd9Sstevel@tonic-gate 		for (i = 0; i < idargc && nids < NIDS; i++) {
3517c478bd9Sstevel@tonic-gate 			if (idtype == P_CID) {
3527c478bd9Sstevel@tonic-gate 				if ((id = clname2cid(idargv[i])) == -1) {
3537c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, "%s: Invalid or"
3547c478bd9Sstevel@tonic-gate 					    " unconfigured class %s in idlist"
3557c478bd9Sstevel@tonic-gate 					    " - ignored\n", cmdpath, idargv[i]);
3567c478bd9Sstevel@tonic-gate 					error = 1;
3577c478bd9Sstevel@tonic-gate 				}
3587c478bd9Sstevel@tonic-gate 			} else {
3597c478bd9Sstevel@tonic-gate 				id = (id_t)str2num(idargv[i], INT_MIN, INT_MAX);
3607c478bd9Sstevel@tonic-gate 				if (errno) {
3617c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr,
3627c478bd9Sstevel@tonic-gate 					    "%s: Invalid id \"%s\"\n",
3637c478bd9Sstevel@tonic-gate 					    cmdpath, idargv[i]);
3647c478bd9Sstevel@tonic-gate 					error = 1;
3657c478bd9Sstevel@tonic-gate 					id = BADPID;
3667c478bd9Sstevel@tonic-gate 				}
3677c478bd9Sstevel@tonic-gate 			}
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 			/*
3707c478bd9Sstevel@tonic-gate 			 * lsearch(3C) adds ids to the idlist,
3717c478bd9Sstevel@tonic-gate 			 * eliminating duplicates.
3727c478bd9Sstevel@tonic-gate 			 */
3737c478bd9Sstevel@tonic-gate 			(void) lsearch((void *)&id, (void *)idlist,
3747c478bd9Sstevel@tonic-gate 			    (size_t *)&nids, sizeof (id), (int (*)())idcompar);
3757c478bd9Sstevel@tonic-gate 		}
3767c478bd9Sstevel@tonic-gate 	}
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	if ((nclass = priocntl(0, 0, PC_GETCLINFO, NULL)) == -1)
3797c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't get number of configured classes, priocntl"
3807c478bd9Sstevel@tonic-gate 		    " system call failed with errno %d\n", cmdpath, errno);
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	if ((clpids = (classpids_t *)malloc(sizeof (classpids_t) * nclass)) ==
3837c478bd9Sstevel@tonic-gate 	    NULL)
3847c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't allocate memory for clpids.\n", cmdpath);
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	for (cid = 1; cid < nclass; cid++) {
3877c478bd9Sstevel@tonic-gate 		pcinfo.pc_cid = cid;
3887c478bd9Sstevel@tonic-gate 		if (priocntl(0, 0, PC_GETCLINFO, (caddr_t)&pcinfo) == -1)
3897c478bd9Sstevel@tonic-gate 			fatalerr("%s: Can't get class name, cid = %ld\n",
3907c478bd9Sstevel@tonic-gate 			    cmdpath, cid);
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 		(void) strncpy(clpids[cid].clp_clname, pcinfo.pc_clname,
3937c478bd9Sstevel@tonic-gate 		    PC_CLNMSZ);
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 		/*
3967c478bd9Sstevel@tonic-gate 		 * The memory allocation for the pidlist uses realloc().
3977c478bd9Sstevel@tonic-gate 		 * A realloc() call is required, when "clp_npids" is
3987c478bd9Sstevel@tonic-gate 		 * equal to "clp_pidlistsz".
3997c478bd9Sstevel@tonic-gate 		 */
4007c478bd9Sstevel@tonic-gate 		clpids[cid].clp_pidlist = (pid_t *)NULL;
4017c478bd9Sstevel@tonic-gate 		clpids[cid].clp_pidlistsz = 0;
4027c478bd9Sstevel@tonic-gate 		clpids[cid].clp_npids = 0;
4037c478bd9Sstevel@tonic-gate 	}
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	/*
4067c478bd9Sstevel@tonic-gate 	 * Build the pidlist.
4077c478bd9Sstevel@tonic-gate 	 */
4087c478bd9Sstevel@tonic-gate 	ids2pids(idtype, idlist, nids, clpids, nclass);
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	/*
4117c478bd9Sstevel@tonic-gate 	 * No need for special privileges any more.
4127c478bd9Sstevel@tonic-gate 	 * Set the effective UID back to the real UID.
4137c478bd9Sstevel@tonic-gate 	 */
4147c478bd9Sstevel@tonic-gate 	if (setuid(getuid()) == -1)
4157c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't set effective UID back to real UID\n",
4167c478bd9Sstevel@tonic-gate 		    cmdpath);
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	pidexists = 0;
4197c478bd9Sstevel@tonic-gate 	for (cid = 1; cid < nclass; cid++) {
4207c478bd9Sstevel@tonic-gate 		if (clpids[cid].clp_npids == 0)
4217c478bd9Sstevel@tonic-gate 			continue;
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 		pidexists = 1;
4247c478bd9Sstevel@tonic-gate 		if (snprintf(subcmd, sizeof (subcmd), "%s/%s/%s%s -d",
4257c478bd9Sstevel@tonic-gate 		    CLASSPATH, clpids[cid].clp_clname, clpids[cid].clp_clname,
4267c478bd9Sstevel@tonic-gate 		    basenm) >= sizeof (subcmd)) {
4277c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
4287c478bd9Sstevel@tonic-gate 			    "Can't generate %s specific subcommand\n",
4297c478bd9Sstevel@tonic-gate 			    clpids[cid].clp_clname);
4307c478bd9Sstevel@tonic-gate 			error = 1;
4317c478bd9Sstevel@tonic-gate 			free(clpids[cid].clp_pidlist);
4327c478bd9Sstevel@tonic-gate 			continue;
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 		if ((pipe_to_subcmd = popen(subcmd, "w")) == NULL) {
4357c478bd9Sstevel@tonic-gate 			(void) printf("%s\n", clpids[cid].clp_clname);
4367c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
4377c478bd9Sstevel@tonic-gate 			    "Can't execute %s specific subcommand\n",
4387c478bd9Sstevel@tonic-gate 			    clpids[cid].clp_clname);
4397c478bd9Sstevel@tonic-gate 			error = 1;
4407c478bd9Sstevel@tonic-gate 			free(clpids[cid].clp_pidlist);
4417c478bd9Sstevel@tonic-gate 			continue;
4427c478bd9Sstevel@tonic-gate 		}
4437c478bd9Sstevel@tonic-gate 		(void) fwrite(clpids[cid].clp_pidlist, sizeof (pid_t),
4447c478bd9Sstevel@tonic-gate 		    clpids[cid].clp_npids, pipe_to_subcmd);
4457c478bd9Sstevel@tonic-gate 		if (pclose(pipe_to_subcmd))
4467c478bd9Sstevel@tonic-gate 			error = 1;
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 		free(clpids[cid].clp_pidlist);
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	free(clpids);
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	if (pidexists == 0)
4547c478bd9Sstevel@tonic-gate 		fatalerr("%s: Process(es) not found.\n", cmdpath);
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	return (error);
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate /*
4617c478bd9Sstevel@tonic-gate  * Execute the appropriate class specific sub-command with the arguments
4627c478bd9Sstevel@tonic-gate  * pointed to by subcmdargv.  If the user specified a class we simply
4637c478bd9Sstevel@tonic-gate  * exec the sub-command for that class.  If no class was specified we
4647c478bd9Sstevel@tonic-gate  * verify that the processes in the set specified by idtype/idargv are
4657c478bd9Sstevel@tonic-gate  * all in the same class and then execute the sub-command for that class.
4667c478bd9Sstevel@tonic-gate  */
4677c478bd9Sstevel@tonic-gate static void
set_procs(char * clname,idtype_t idtype,int idargc,char ** idargv,char ** subcmdargv)468*e0a59e98SToomas Soome set_procs(char *clname, idtype_t idtype, int idargc, char **idargv,
469*e0a59e98SToomas Soome     char **subcmdargv)
4707c478bd9Sstevel@tonic-gate {
4717c478bd9Sstevel@tonic-gate 	char			idstr[PC_IDTYPNMSZ];
4727c478bd9Sstevel@tonic-gate 	char			myidstr[PC_IDTYPNMSZ];
4737c478bd9Sstevel@tonic-gate 	char			clnmbuf[PC_CLNMSZ];
4747c478bd9Sstevel@tonic-gate 	pcinfo_t		pcinfo;
4757c478bd9Sstevel@tonic-gate 	static psinfo_t		prinfo;
4767c478bd9Sstevel@tonic-gate 	static prcred_t		prcred;
4777c478bd9Sstevel@tonic-gate 	DIR			*dirp;
4787c478bd9Sstevel@tonic-gate 	struct dirent		*dentp;
4797c478bd9Sstevel@tonic-gate 	static char		pname[100];
4807c478bd9Sstevel@tonic-gate 	char			*fname;
4817c478bd9Sstevel@tonic-gate 	int			procfd;
4827c478bd9Sstevel@tonic-gate 	int			saverr;
4837c478bd9Sstevel@tonic-gate 	static char		subcmdpath[128];
4847c478bd9Sstevel@tonic-gate 	boolean_t		procinset;
4857c478bd9Sstevel@tonic-gate 	id_t			id;
4867c478bd9Sstevel@tonic-gate 	size_t			len;
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	if (clname == NULL && idtype == P_PID && idargc <= 1) {
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 		/*
4917c478bd9Sstevel@tonic-gate 		 * No class specified by user but only one process
4927c478bd9Sstevel@tonic-gate 		 * in specified set.  Get the class the easy way.
4937c478bd9Sstevel@tonic-gate 		 */
4947c478bd9Sstevel@tonic-gate 		if (idargc == 0) {
4957c478bd9Sstevel@tonic-gate 			if (priocntl(P_PID, P_MYID, PC_GETXPARMS, NULL,
4967c478bd9Sstevel@tonic-gate 			    PC_KY_CLNAME, clnmbuf, 0) == -1)
4977c478bd9Sstevel@tonic-gate 				if (errno == ESRCH)
4987c478bd9Sstevel@tonic-gate 					fatalerr("%s: Process not found.\n",
4997c478bd9Sstevel@tonic-gate 					    cmdpath);
5007c478bd9Sstevel@tonic-gate 				else
5017c478bd9Sstevel@tonic-gate 					fatalerr("%s: Can't get class of"
5027c478bd9Sstevel@tonic-gate 					    " current process\npriocntl"
5037c478bd9Sstevel@tonic-gate 					    " system call failed with"
5047c478bd9Sstevel@tonic-gate 					    " errno %d\n", cmdpath, errno);
5057c478bd9Sstevel@tonic-gate 		} else {
5067c478bd9Sstevel@tonic-gate 			/* idargc == 1 */
5077c478bd9Sstevel@tonic-gate 			id = (id_t)str2num(idargv[0], INT_MIN, INT_MAX);
5087c478bd9Sstevel@tonic-gate 			if (errno)
5097c478bd9Sstevel@tonic-gate 				fatalerr("%s: Invalid id \"%s\"\n", cmdpath,
5107c478bd9Sstevel@tonic-gate 				    idargv[0]);
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 			if (priocntl(P_PID, id, PC_GETXPARMS,
5137c478bd9Sstevel@tonic-gate 			    NULL, PC_KY_CLNAME, clnmbuf, 0) == -1)
5147c478bd9Sstevel@tonic-gate 				if (errno == ESRCH)
5157c478bd9Sstevel@tonic-gate 					fatalerr("%s: Process not found.\n",
5167c478bd9Sstevel@tonic-gate 					    cmdpath);
5177c478bd9Sstevel@tonic-gate 				else
5187c478bd9Sstevel@tonic-gate 					fatalerr("%s: Can't get class of "
5197c478bd9Sstevel@tonic-gate 					    " specified  process\npriocntl"
5207c478bd9Sstevel@tonic-gate 					    " system call failed with"
5217c478bd9Sstevel@tonic-gate 					    " errno %d\n", cmdpath, errno);
5227c478bd9Sstevel@tonic-gate 		}
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 		clname = clnmbuf;
5257c478bd9Sstevel@tonic-gate 	} else if (clname == NULL) {
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 		/*
5287c478bd9Sstevel@tonic-gate 		 * No class specified by user and potentially more
5297c478bd9Sstevel@tonic-gate 		 * than one process in specified set.  Verify that
5307c478bd9Sstevel@tonic-gate 		 * all procs in set are in the same class.
5317c478bd9Sstevel@tonic-gate 		 */
5327c478bd9Sstevel@tonic-gate 		if (idargc == 0 && idtype != P_ALL) {
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 			/*
5357c478bd9Sstevel@tonic-gate 			 * No ids supplied by user; use current id.
5367c478bd9Sstevel@tonic-gate 			 */
5377c478bd9Sstevel@tonic-gate 			if (getmyidstr(idtype, myidstr) == -1)
5387c478bd9Sstevel@tonic-gate 				fatalerr("%s: Can't get ID string for current"
5397c478bd9Sstevel@tonic-gate 				    " process, idtype = %d\n", cmdpath, idtype);
5407c478bd9Sstevel@tonic-gate 		}
5417c478bd9Sstevel@tonic-gate 		if ((dirp = opendir(procdir)) == NULL)
5427c478bd9Sstevel@tonic-gate 			fatalerr("%s: Can't open PROC directory %s\n",
5437c478bd9Sstevel@tonic-gate 			    cmdpath, procdir);
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 		while ((dentp = readdir(dirp)) != NULL) {
5467c478bd9Sstevel@tonic-gate 			if (dentp->d_name[0] == '.')	/* skip . and .. */
5477c478bd9Sstevel@tonic-gate 				continue;
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate 			len = snprintf(pname, sizeof (pname), "%s/%s/",
5507c478bd9Sstevel@tonic-gate 			    procdir, dentp->d_name);
5517c478bd9Sstevel@tonic-gate 			/* Really max(sizeof ("psinfo"), sizeof ("cred")) */
5527c478bd9Sstevel@tonic-gate 			if (len + sizeof ("psinfo") > sizeof (pname)) {
5537c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
5547c478bd9Sstevel@tonic-gate 				    "%s: skipping %s, name too long.\n",
5557c478bd9Sstevel@tonic-gate 				    cmdpath, dentp->d_name);
5567c478bd9Sstevel@tonic-gate 				continue;
5577c478bd9Sstevel@tonic-gate 			}
5587c478bd9Sstevel@tonic-gate 			fname = pname + len;
5597c478bd9Sstevel@tonic-gate retry:
5607c478bd9Sstevel@tonic-gate 			(void) strcpy(fname, "psinfo");
5617c478bd9Sstevel@tonic-gate 			if ((procfd = open(pname, O_RDONLY)) < 0)
5627c478bd9Sstevel@tonic-gate 				continue;
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 			if (read(procfd, &prinfo, sizeof (prinfo)) !=
5657c478bd9Sstevel@tonic-gate 			    sizeof (prinfo)) {
5667c478bd9Sstevel@tonic-gate 				saverr = errno;
5677c478bd9Sstevel@tonic-gate 				(void) close(procfd);
5687c478bd9Sstevel@tonic-gate 				if (saverr == EAGAIN)
5697c478bd9Sstevel@tonic-gate 					goto retry;
5707c478bd9Sstevel@tonic-gate 				if (saverr != ENOENT) {
5717c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr,
5727c478bd9Sstevel@tonic-gate 					    "%s: Can't get process info for"
5737c478bd9Sstevel@tonic-gate 					    " %s\n", cmdpath, pname);
5747c478bd9Sstevel@tonic-gate 				}
5757c478bd9Sstevel@tonic-gate 				continue;
5767c478bd9Sstevel@tonic-gate 			}
5777c478bd9Sstevel@tonic-gate 			(void) close(procfd);
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 			if (idtype == P_UID || idtype == P_GID) {
5807c478bd9Sstevel@tonic-gate 				(void) strcpy(fname, "cred");
5817c478bd9Sstevel@tonic-gate 				if ((procfd = open(pname, O_RDONLY)) < 0 ||
5827c478bd9Sstevel@tonic-gate 				    read(procfd, &prcred, sizeof (prcred)) !=
5837c478bd9Sstevel@tonic-gate 				    sizeof (prcred)) {
5847c478bd9Sstevel@tonic-gate 					saverr = errno;
5857c478bd9Sstevel@tonic-gate 					if (procfd >= 0)
5867c478bd9Sstevel@tonic-gate 						(void) close(procfd);
5877c478bd9Sstevel@tonic-gate 					if (saverr == EAGAIN)
5887c478bd9Sstevel@tonic-gate 						goto retry;
5897c478bd9Sstevel@tonic-gate 					if (saverr != ENOENT) {
5907c478bd9Sstevel@tonic-gate 						(void) fprintf(stderr,
5917c478bd9Sstevel@tonic-gate 						    "%s: Can't get process"
5927c478bd9Sstevel@tonic-gate 						    " credentials for %s\n",
5937c478bd9Sstevel@tonic-gate 						    cmdpath, pname);
5947c478bd9Sstevel@tonic-gate 					}
5957c478bd9Sstevel@tonic-gate 					continue;
5967c478bd9Sstevel@tonic-gate 				}
5977c478bd9Sstevel@tonic-gate 				(void) close(procfd);
5987c478bd9Sstevel@tonic-gate 			}
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate 			if (prinfo.pr_lwp.pr_state == 0 || prinfo.pr_nlwp == 0)
6017c478bd9Sstevel@tonic-gate 				continue;
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate 			switch (idtype) {
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 			case P_PID:
6077c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_pid, idstr);
6087c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6097c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6107c478bd9Sstevel@tonic-gate 				break;
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate 			case P_PPID:
6137c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_ppid, idstr);
6147c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6157c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6167c478bd9Sstevel@tonic-gate 				break;
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 			case P_PGID:
6197c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_pgid, idstr);
6207c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6217c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6227c478bd9Sstevel@tonic-gate 				break;
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 			case P_SID:
6257c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_sid, idstr);
6267c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6277c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6287c478bd9Sstevel@tonic-gate 				break;
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 			case P_CID:
6317c478bd9Sstevel@tonic-gate 				procinset = idmatch(prinfo.pr_lwp.pr_clname,
6327c478bd9Sstevel@tonic-gate 				    myidstr, idargc, idargv);
6337c478bd9Sstevel@tonic-gate 				break;
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 			case P_UID:
6367c478bd9Sstevel@tonic-gate 				itoa((long)prcred.pr_euid, idstr);
6377c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6387c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6397c478bd9Sstevel@tonic-gate 				break;
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 			case P_GID:
6427c478bd9Sstevel@tonic-gate 				itoa((long)prcred.pr_egid, idstr);
6437c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6447c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6457c478bd9Sstevel@tonic-gate 				break;
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 			case P_PROJID:
6487c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_projid, idstr);
6497c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6507c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6517c478bd9Sstevel@tonic-gate 				break;
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 			case P_TASKID:
6547c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_taskid, idstr);
6557c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6567c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6577c478bd9Sstevel@tonic-gate 				break;
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 			case P_ZONEID:
6607c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_zoneid, idstr);
6617c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6627c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6637c478bd9Sstevel@tonic-gate 				break;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 			case P_CTID:
6667c478bd9Sstevel@tonic-gate 				itoa((long)prinfo.pr_contract, idstr);
6677c478bd9Sstevel@tonic-gate 				procinset = idmatch(idstr, myidstr,
6687c478bd9Sstevel@tonic-gate 				    idargc, idargv);
6697c478bd9Sstevel@tonic-gate 				break;
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 			case P_ALL:
6727c478bd9Sstevel@tonic-gate 				procinset = B_TRUE;
6737c478bd9Sstevel@tonic-gate 				break;
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 			default:
6767c478bd9Sstevel@tonic-gate 				fatalerr("%s: Bad idtype %d in set_procs()\n",
6777c478bd9Sstevel@tonic-gate 				    cmdpath, idtype);
6787c478bd9Sstevel@tonic-gate 			}
6797c478bd9Sstevel@tonic-gate 			if (procinset == B_TRUE) {
6807c478bd9Sstevel@tonic-gate 				if (clname == NULL) {
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate 					/*
6837c478bd9Sstevel@tonic-gate 					 * First proc found in set.
6847c478bd9Sstevel@tonic-gate 					 */
6857c478bd9Sstevel@tonic-gate 					(void) strcpy(clnmbuf,
6867c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname);
6877c478bd9Sstevel@tonic-gate 					clname = clnmbuf;
6887c478bd9Sstevel@tonic-gate 				} else if (strcmp(clname,
6897c478bd9Sstevel@tonic-gate 				    prinfo.pr_lwp.pr_clname) != 0) {
6907c478bd9Sstevel@tonic-gate 					fatalerr("%s: Specified processes"
6917c478bd9Sstevel@tonic-gate 					    " from different classes.\n",
6927c478bd9Sstevel@tonic-gate 					    cmdpath);
6937c478bd9Sstevel@tonic-gate 				}
6947c478bd9Sstevel@tonic-gate 			}
6957c478bd9Sstevel@tonic-gate 		}
6967c478bd9Sstevel@tonic-gate 		(void) closedir(dirp);
6977c478bd9Sstevel@tonic-gate 		if (clname == NULL)
6987c478bd9Sstevel@tonic-gate 			fatalerr("%s: Process(es) not found.\n", cmdpath);
6997c478bd9Sstevel@tonic-gate 	} else {
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 		/*
7027c478bd9Sstevel@tonic-gate 		 * User specified class. Check it for validity.
7037c478bd9Sstevel@tonic-gate 		 */
7047c478bd9Sstevel@tonic-gate 		(void) strcpy(pcinfo.pc_clname, clname);
7057c478bd9Sstevel@tonic-gate 		if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1)
7067c478bd9Sstevel@tonic-gate 			fatalerr("%s: Invalid or unconfigured class %s\n",
7077c478bd9Sstevel@tonic-gate 			    cmdpath, clname);
7087c478bd9Sstevel@tonic-gate 	}
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 	/*
7117c478bd9Sstevel@tonic-gate 	 * No need for special privileges any more.
7127c478bd9Sstevel@tonic-gate 	 * Set the effective UID back to the real UID.
7137c478bd9Sstevel@tonic-gate 	 */
7147c478bd9Sstevel@tonic-gate 	if (setuid(getuid()) == -1)
7157c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't set effective UID back to real UID\n",
7167c478bd9Sstevel@tonic-gate 		    cmdpath);
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	if (snprintf(subcmdpath, sizeof (subcmdpath), "%s/%s/%s%s",
7197c478bd9Sstevel@tonic-gate 	    CLASSPATH, clname, clname, basenm) >= sizeof (subcmdpath))
7207c478bd9Sstevel@tonic-gate 		fatalerr("%s: can't generate %s specific subcommand\n",
7217c478bd9Sstevel@tonic-gate 		    cmdpath, clname);
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 	subcmdargv[0] = subcmdpath;
7247c478bd9Sstevel@tonic-gate 	(void) execv(subcmdpath, subcmdargv);
7257c478bd9Sstevel@tonic-gate 	fatalerr("%s: Can't execute %s sub-command\n", cmdpath, clname);
7267c478bd9Sstevel@tonic-gate }
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate /*
7307c478bd9Sstevel@tonic-gate  * Execute the appropriate class specific sub-command with the arguments
7317c478bd9Sstevel@tonic-gate  * pointed to by subcmdargv.  If the user specified a class we simply
7327c478bd9Sstevel@tonic-gate  * exec the sub-command for that class.  If no class was specified we
7337c478bd9Sstevel@tonic-gate  * execute the sub-command for our own current class.
7347c478bd9Sstevel@tonic-gate  */
7357c478bd9Sstevel@tonic-gate static void
exec_cmd(char * clname,char ** subcmdargv)736*e0a59e98SToomas Soome exec_cmd(char *clname, char **subcmdargv)
7377c478bd9Sstevel@tonic-gate {
7387c478bd9Sstevel@tonic-gate 	pcinfo_t	pcinfo;
7397c478bd9Sstevel@tonic-gate 	char		clnmbuf[PC_CLNMSZ];
7407c478bd9Sstevel@tonic-gate 	char		subcmdpath[128];
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	/*
7437c478bd9Sstevel@tonic-gate 	 * No special privileges required for this operation.
7447c478bd9Sstevel@tonic-gate 	 * Set the effective UID back to the real UID.
7457c478bd9Sstevel@tonic-gate 	 */
7467c478bd9Sstevel@tonic-gate 	if (setuid(getuid()) == -1)
7477c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't set effective UID back to real UID\n",
7487c478bd9Sstevel@tonic-gate 		    cmdpath);
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 	if (clname == NULL) {
7517c478bd9Sstevel@tonic-gate 		if (priocntl(P_PID, P_MYID, PC_GETXPARMS, NULL,
7527c478bd9Sstevel@tonic-gate 		    PC_KY_CLNAME, clnmbuf, 0) == -1)
7537c478bd9Sstevel@tonic-gate 			fatalerr("%s: Can't get class name of current process\n"
7547c478bd9Sstevel@tonic-gate 			    "priocntl system call failed with errno %d\n",
7557c478bd9Sstevel@tonic-gate 			    cmdpath, errno);
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 		clname = clnmbuf;
7587c478bd9Sstevel@tonic-gate 	} else {
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 		/*
7617c478bd9Sstevel@tonic-gate 		 * User specified class. Check it for validity.
7627c478bd9Sstevel@tonic-gate 		 */
7637c478bd9Sstevel@tonic-gate 		(void) strcpy(pcinfo.pc_clname, clname);
7647c478bd9Sstevel@tonic-gate 		if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1)
7657c478bd9Sstevel@tonic-gate 			fatalerr("%s: Invalid or unconfigured class %s\n",
7667c478bd9Sstevel@tonic-gate 			    cmdpath, clname);
7677c478bd9Sstevel@tonic-gate 	}
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 	if (snprintf(subcmdpath, sizeof (subcmdpath), "%s/%s/%s%s",
7707c478bd9Sstevel@tonic-gate 	    CLASSPATH, clname, clname, basenm) >= sizeof (subcmdpath))
7717c478bd9Sstevel@tonic-gate 		fatalerr("%s: can't generate %s specific subcommand\n",
7727c478bd9Sstevel@tonic-gate 		    cmdpath, clname);
7737c478bd9Sstevel@tonic-gate 	subcmdargv[0] = subcmdpath;
7747c478bd9Sstevel@tonic-gate 	(void) execv(subcmdpath, subcmdargv);
7757c478bd9Sstevel@tonic-gate 	fatalerr("%s: Can't execute %s sub-command\n", cmdpath, clname);
7767c478bd9Sstevel@tonic-gate }
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate /*
7807c478bd9Sstevel@tonic-gate  * Fill in the classpids structures in the array pointed to by clpids
7817c478bd9Sstevel@tonic-gate  * with pids for the processes in the set specified by idtype/idlist.
7827c478bd9Sstevel@tonic-gate  * We read the /proc/<pid>/psinfo file to get the necessary process
7837c478bd9Sstevel@tonic-gate  * information.
7847c478bd9Sstevel@tonic-gate  */
7857c478bd9Sstevel@tonic-gate static void
ids2pids(idtype_t idtype,id_t * idlist,int nids,classpids_t * clpids,int nclass)786*e0a59e98SToomas Soome ids2pids(idtype_t idtype, id_t *idlist, int nids, classpids_t *clpids,
787*e0a59e98SToomas Soome     int	 nclass)
7887c478bd9Sstevel@tonic-gate {
7897c478bd9Sstevel@tonic-gate 	static psinfo_t		prinfo;
7907c478bd9Sstevel@tonic-gate 	static prcred_t		prcred;
7917c478bd9Sstevel@tonic-gate 	DIR			*dirp;
7927c478bd9Sstevel@tonic-gate 	struct dirent		*dentp;
7937c478bd9Sstevel@tonic-gate 	char			pname[100];
7947c478bd9Sstevel@tonic-gate 	char			*fname;
7957c478bd9Sstevel@tonic-gate 	int			procfd;
7967c478bd9Sstevel@tonic-gate 	int			saverr;
7977c478bd9Sstevel@tonic-gate 	int			i;
7987c478bd9Sstevel@tonic-gate 	char			*clname;
7997c478bd9Sstevel@tonic-gate 	size_t			len;
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	if ((dirp = opendir(procdir)) == NULL)
8027c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't open PROC directory %s\n",
8037c478bd9Sstevel@tonic-gate 		    cmdpath, procdir);
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	while ((dentp = readdir(dirp)) != NULL) {
8067c478bd9Sstevel@tonic-gate 		if (dentp->d_name[0] == '.')	/* skip . and .. */
8077c478bd9Sstevel@tonic-gate 			continue;
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 		len = snprintf(pname, sizeof (pname), "%s/%s/",
8107c478bd9Sstevel@tonic-gate 		    procdir, dentp->d_name);
8117c478bd9Sstevel@tonic-gate 		/* Really max(sizeof ("psinfo"), sizeof ("cred")) */
8127c478bd9Sstevel@tonic-gate 		if (len + sizeof ("psinfo") > sizeof (pname)) {
8137c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
8147c478bd9Sstevel@tonic-gate 			    "%s: skipping %s, name too long.\n",
8157c478bd9Sstevel@tonic-gate 			    cmdpath, dentp->d_name);
8167c478bd9Sstevel@tonic-gate 			continue;
8177c478bd9Sstevel@tonic-gate 		}
8187c478bd9Sstevel@tonic-gate 		fname = pname + len;
8197c478bd9Sstevel@tonic-gate retry:
8207c478bd9Sstevel@tonic-gate 		(void) strcpy(fname, "psinfo");
8217c478bd9Sstevel@tonic-gate 		if ((procfd = open(pname, O_RDONLY)) < 0)
8227c478bd9Sstevel@tonic-gate 			continue;
8237c478bd9Sstevel@tonic-gate 		if (read(procfd, &prinfo, sizeof (prinfo)) != sizeof (prinfo)) {
8247c478bd9Sstevel@tonic-gate 			saverr = errno;
8257c478bd9Sstevel@tonic-gate 			(void) close(procfd);
8267c478bd9Sstevel@tonic-gate 			if (saverr == EAGAIN)
8277c478bd9Sstevel@tonic-gate 				goto retry;
8287c478bd9Sstevel@tonic-gate 			if (saverr != ENOENT) {
8297c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
8307c478bd9Sstevel@tonic-gate 				    "%s: Can't get process info for %s\n",
8317c478bd9Sstevel@tonic-gate 				    cmdpath, pname);
8327c478bd9Sstevel@tonic-gate 			}
8337c478bd9Sstevel@tonic-gate 			continue;
8347c478bd9Sstevel@tonic-gate 		}
8357c478bd9Sstevel@tonic-gate 		(void) close(procfd);
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate 		if (idtype == P_UID || idtype == P_GID) {
8387c478bd9Sstevel@tonic-gate 			(void) strcpy(fname, "cred");
8397c478bd9Sstevel@tonic-gate 			if ((procfd = open(pname, O_RDONLY)) < 0 ||
8407c478bd9Sstevel@tonic-gate 			    read(procfd, &prcred, sizeof (prcred)) !=
8417c478bd9Sstevel@tonic-gate 			    sizeof (prcred)) {
8427c478bd9Sstevel@tonic-gate 				saverr = errno;
8437c478bd9Sstevel@tonic-gate 				(void) close(procfd);
8447c478bd9Sstevel@tonic-gate 				if (saverr == EAGAIN)
8457c478bd9Sstevel@tonic-gate 					goto retry;
8467c478bd9Sstevel@tonic-gate 				if (saverr != ENOENT) {
8477c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr,
8487c478bd9Sstevel@tonic-gate 					    "%s: Can't get process credentials"
8497c478bd9Sstevel@tonic-gate 					    " for %s\n",
8507c478bd9Sstevel@tonic-gate 					    cmdpath, pname);
8517c478bd9Sstevel@tonic-gate 				}
8527c478bd9Sstevel@tonic-gate 				continue;
8537c478bd9Sstevel@tonic-gate 			}
8547c478bd9Sstevel@tonic-gate 			(void) close(procfd);
8557c478bd9Sstevel@tonic-gate 		}
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 		if (prinfo.pr_lwp.pr_state == 0 || prinfo.pr_nlwp == 0)
8587c478bd9Sstevel@tonic-gate 			continue;
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate 		switch (idtype) {
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 		case P_PID:
8637c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
8647c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_pid)
8657c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
8667c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
8677c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
8687c478bd9Sstevel@tonic-gate 			}
8697c478bd9Sstevel@tonic-gate 			break;
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 		case P_PPID:
8727c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
8737c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_ppid)
8747c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
8757c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
8767c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
8777c478bd9Sstevel@tonic-gate 			}
8787c478bd9Sstevel@tonic-gate 			break;
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 		case P_PGID:
8817c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
8827c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_pgid)
8837c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
8847c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
8857c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
8867c478bd9Sstevel@tonic-gate 			}
8877c478bd9Sstevel@tonic-gate 			break;
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate 		case P_SID:
8907c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
8917c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_sid)
8927c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
8937c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
8947c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
8957c478bd9Sstevel@tonic-gate 			}
8967c478bd9Sstevel@tonic-gate 			break;
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 		case P_CID:
8997c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9007c478bd9Sstevel@tonic-gate 				clname = clpids[idlist[i]].clp_clname;
9017c478bd9Sstevel@tonic-gate 				if (strcmp(clname,
9027c478bd9Sstevel@tonic-gate 				    prinfo.pr_lwp.pr_clname) == 0)
9037c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9047c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9057c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9067c478bd9Sstevel@tonic-gate 			}
9077c478bd9Sstevel@tonic-gate 			break;
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate 		case P_UID:
9107c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9117c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prcred.pr_euid)
9127c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9137c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9147c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9157c478bd9Sstevel@tonic-gate 			}
9167c478bd9Sstevel@tonic-gate 			break;
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 		case P_GID:
9197c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9207c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prcred.pr_egid)
9217c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9227c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9237c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9247c478bd9Sstevel@tonic-gate 			}
9257c478bd9Sstevel@tonic-gate 			break;
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate 		case P_PROJID:
9287c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9297c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_projid)
9307c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9317c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9327c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9337c478bd9Sstevel@tonic-gate 			}
9347c478bd9Sstevel@tonic-gate 			break;
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 		case P_TASKID:
9377c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9387c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_taskid)
9397c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9407c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9417c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9427c478bd9Sstevel@tonic-gate 			}
9437c478bd9Sstevel@tonic-gate 		break;
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate 		case P_ZONEID:
9467c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9477c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_zoneid)
9487c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9497c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9507c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9517c478bd9Sstevel@tonic-gate 			}
9527c478bd9Sstevel@tonic-gate 			break;
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate 		case P_CTID:
9557c478bd9Sstevel@tonic-gate 			for (i = 0; i < nids; i++) {
9567c478bd9Sstevel@tonic-gate 				if (idlist[i] == (id_t)prinfo.pr_contract)
9577c478bd9Sstevel@tonic-gate 					add_pid_tolist(clpids, nclass,
9587c478bd9Sstevel@tonic-gate 					    prinfo.pr_lwp.pr_clname,
9597c478bd9Sstevel@tonic-gate 					    prinfo.pr_pid);
9607c478bd9Sstevel@tonic-gate 			}
9617c478bd9Sstevel@tonic-gate 			break;
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 		case P_ALL:
9647c478bd9Sstevel@tonic-gate 			add_pid_tolist(clpids, nclass, prinfo.pr_lwp.pr_clname,
9657c478bd9Sstevel@tonic-gate 			    prinfo.pr_pid);
9667c478bd9Sstevel@tonic-gate 			break;
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate 		default:
9697c478bd9Sstevel@tonic-gate 			fatalerr("%s: Bad idtype %d in ids2pids()\n",
9707c478bd9Sstevel@tonic-gate 			    cmdpath, idtype);
9717c478bd9Sstevel@tonic-gate 		}
9727c478bd9Sstevel@tonic-gate 	}
9737c478bd9Sstevel@tonic-gate 	(void) closedir(dirp);
9747c478bd9Sstevel@tonic-gate }
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate /*
9787c478bd9Sstevel@tonic-gate  * Search the array pointed to by clpids for the classpids
9797c478bd9Sstevel@tonic-gate  * structure corresponding to clname and add pid to its
9807c478bd9Sstevel@tonic-gate  * pidlist.
9817c478bd9Sstevel@tonic-gate  */
9827c478bd9Sstevel@tonic-gate static void
add_pid_tolist(classpids_t * clpids,int nclass,char * clname,pid_t pid)983*e0a59e98SToomas Soome add_pid_tolist(classpids_t *clpids, int nclass, char *clname, pid_t pid)
9847c478bd9Sstevel@tonic-gate {
9857c478bd9Sstevel@tonic-gate 	classpids_t	*clp;
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate 	for (clp = clpids; clp != &clpids[nclass]; clp++) {
9887c478bd9Sstevel@tonic-gate 		if (strcmp(clp->clp_clname, clname) == 0) {
9897c478bd9Sstevel@tonic-gate 			if (clp->clp_npids == clp->clp_pidlistsz)
9907c478bd9Sstevel@tonic-gate 				increase_pidlist(clp);
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 			(clp->clp_pidlist)[clp->clp_npids] = pid;
9937c478bd9Sstevel@tonic-gate 			clp->clp_npids++;
9947c478bd9Sstevel@tonic-gate 			return;
9957c478bd9Sstevel@tonic-gate 		}
9967c478bd9Sstevel@tonic-gate 	}
9977c478bd9Sstevel@tonic-gate }
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate static void
increase_pidlist(classpids_t * clp)10017c478bd9Sstevel@tonic-gate increase_pidlist(classpids_t *clp)
10027c478bd9Sstevel@tonic-gate {
10037c478bd9Sstevel@tonic-gate 	if ((clp->clp_pidlist = realloc(clp->clp_pidlist,
10047c478bd9Sstevel@tonic-gate 	    (clp->clp_pidlistsz + NPIDS) * sizeof (pid_t))) == NULL)
10057c478bd9Sstevel@tonic-gate 		/*
10067c478bd9Sstevel@tonic-gate 		 * The pidlist is filled up and we cannot increase the size.
10077c478bd9Sstevel@tonic-gate 		 */
10087c478bd9Sstevel@tonic-gate 		fatalerr("%s: Can't allocate memory for pidlist.\n", cmdpath);
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 	clp->clp_pidlistsz += NPIDS;
10117c478bd9Sstevel@tonic-gate }
10127c478bd9Sstevel@tonic-gate 
10137c478bd9Sstevel@tonic-gate 
10147c478bd9Sstevel@tonic-gate /*
10157c478bd9Sstevel@tonic-gate  * Compare id strings for equality.  If idargv contains ids
10167c478bd9Sstevel@tonic-gate  * (idargc > 0) compare idstr to each id in idargv, otherwise
10177c478bd9Sstevel@tonic-gate  * just compare to curidstr.
10187c478bd9Sstevel@tonic-gate  */
10197c478bd9Sstevel@tonic-gate static boolean_t
idmatch(char * idstr,char * curidstr,int idargc,char ** idargv)1020*e0a59e98SToomas Soome idmatch(char *idstr, char *curidstr, int idargc, char **idargv)
10217c478bd9Sstevel@tonic-gate {
10227c478bd9Sstevel@tonic-gate 	int	i;
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate 	if (idargc == 0) {
10257c478bd9Sstevel@tonic-gate 		if (strcmp(curidstr, idstr) == 0)
10267c478bd9Sstevel@tonic-gate 			return (B_TRUE);
10277c478bd9Sstevel@tonic-gate 	} else {
10287c478bd9Sstevel@tonic-gate 		for (i = 0; i < idargc; i++) {
10297c478bd9Sstevel@tonic-gate 			if (strcmp(idargv[i], idstr) == 0)
10307c478bd9Sstevel@tonic-gate 				return (B_TRUE);
10317c478bd9Sstevel@tonic-gate 		}
10327c478bd9Sstevel@tonic-gate 	}
10337c478bd9Sstevel@tonic-gate 	return (B_FALSE);
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate /*
10377c478bd9Sstevel@tonic-gate  * This is a copy of the getopt() function found in libc:getopt.c. A separate
10387c478bd9Sstevel@tonic-gate  * copy is required to fix the bug id #1114636. To fix the problem we need to
10397c478bd9Sstevel@tonic-gate  * reset the _sp to 1. Since _sp in libc:getopt() is not exposed, a copy of
10407c478bd9Sstevel@tonic-gate  * the getopt() is kept so that prio_sp can be reset to 1.
10417c478bd9Sstevel@tonic-gate  */
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate static int
prio_getopt(int argc,char * const * argv,char * opts)1044*e0a59e98SToomas Soome prio_getopt(int argc, char * const *argv, char *opts)
10457c478bd9Sstevel@tonic-gate {
1046*e0a59e98SToomas Soome 	char c;
1047*e0a59e98SToomas Soome 	char *cp;
10487c478bd9Sstevel@tonic-gate 
10497c478bd9Sstevel@tonic-gate 	if (prio_sp == 1)
10507c478bd9Sstevel@tonic-gate 		if (prio_optind >= argc ||
10517c478bd9Sstevel@tonic-gate 		    argv[prio_optind][0] != '-' || argv[prio_optind][1] == '\0')
10527c478bd9Sstevel@tonic-gate 			return (EOF);
1053*e0a59e98SToomas Soome 		else if (strcmp(argv[prio_optind], "--") == 0) {
10547c478bd9Sstevel@tonic-gate 			prio_optind++;
10557c478bd9Sstevel@tonic-gate 			return (EOF);
10567c478bd9Sstevel@tonic-gate 		}
10577c478bd9Sstevel@tonic-gate 	prio_optopt = c = (unsigned char)argv[prio_optind][prio_sp];
10587c478bd9Sstevel@tonic-gate 	if (c == ':' || (cp = strchr(opts, c)) == NULL) {
10597c478bd9Sstevel@tonic-gate 		if (argv[prio_optind][++prio_sp] == '\0') {
10607c478bd9Sstevel@tonic-gate 			prio_optind++;
10617c478bd9Sstevel@tonic-gate 			prio_sp = 1;
10627c478bd9Sstevel@tonic-gate 		}
10637c478bd9Sstevel@tonic-gate 		return ('?');
10647c478bd9Sstevel@tonic-gate 	}
10657c478bd9Sstevel@tonic-gate 	if (*++cp == ':') {
10667c478bd9Sstevel@tonic-gate 		if (argv[prio_optind][prio_sp+1] != '\0')
10677c478bd9Sstevel@tonic-gate 			prio_optarg = &argv[prio_optind++][prio_sp+1];
10687c478bd9Sstevel@tonic-gate 		else if (++prio_optind >= argc) {
10697c478bd9Sstevel@tonic-gate 			prio_sp = 1;
10707c478bd9Sstevel@tonic-gate 			return ('?');
10717c478bd9Sstevel@tonic-gate 		} else
10727c478bd9Sstevel@tonic-gate 			prio_optarg = argv[prio_optind++];
10737c478bd9Sstevel@tonic-gate 		prio_sp = 1;
10747c478bd9Sstevel@tonic-gate 	} else {
10757c478bd9Sstevel@tonic-gate 		if (argv[prio_optind][++prio_sp] == '\0') {
10767c478bd9Sstevel@tonic-gate 			prio_sp = 1;
10777c478bd9Sstevel@tonic-gate 			prio_optind++;
10787c478bd9Sstevel@tonic-gate 		}
10797c478bd9Sstevel@tonic-gate 		prio_optarg = NULL;
10807c478bd9Sstevel@tonic-gate 	}
10817c478bd9Sstevel@tonic-gate 	return (c);
10827c478bd9Sstevel@tonic-gate }
1083