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