4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
39 #include <sys/types.h>
42 #include <sys/param.h>
43 #include <sys/procset.h>
44 #include <sys/priocntl.h>
54 * This file contains the code implementing the class independent part
55 * of the priocntl command. Most of the useful work for the priocntl
56 * command is done by the class specific sub-commands, the code for
57 * which is elsewhere. The class independent part of the command is
58 * responsible for executing the appropriate class specific sub-commands
59 * and providing any necessary input to the sub-commands.
60 * Code in this file should never assume any knowledge of any specific
61 * scheduler class (other than the SYS class).
64 #define CLASSPATH "/usr/lib/class"
66 typedef struct classpids
{
67 char clp_clname
[PC_CLNMSZ
];
74 "usage: priocntl -l\n\
75 priocntl -d [-i idtype] [idlist]\n\
76 priocntl -s [-c class] [c.s.o.] [-i idtype] [idlist]\n\
77 priocntl -e [-c class] [c.s.o.] command [argument(s)]\n";
79 static char basenm
[BASENMSZ
];
80 static char cmdpath
[MAXPATHLEN
];
82 static char *procdir
= "/proc";
84 static int print_classlist(void);
85 static void set_procs(char *, idtype_t
, int, char **, char **);
86 static void exec_cmd(char *, char **);
87 static int print_procs(idtype_t
, int, char *[]);
88 static void ids2pids(idtype_t
, id_t
*, int, classpids_t
*, int);
89 static void add_pid_tolist(classpids_t
*, int, char *, pid_t
);
90 static void increase_pidlist(classpids_t
*);
91 static boolean_t
idmatch(char *, char *, int, char **);
94 * These variables are defined to be used in prio_getopt() below.
96 static int prio_getopt();
97 /* LINTED static unused */
98 static int prio_optopt
= 0;
99 static char *prio_optarg
= 0;
100 static int prio_optind
= 1;
101 static int prio_sp
= 1;
104 main(int argc
, char *argv
[])
107 int lflag
, dflag
, sflag
, eflag
, cflag
, iflag
, csoptsflag
;
114 (void) strlcpy(cmdpath
, argv
[0], MAXPATHLEN
);
115 (void) strlcpy(basenm
, basename(argv
[0]), BASENMSZ
);
116 lflag
= dflag
= sflag
= eflag
= cflag
= iflag
= csoptsflag
= 0;
117 while ((c
= prio_getopt(argc
, argv
, "ldsec:i:")) != -1) {
139 clname
= prio_optarg
;
144 idtypnm
= prio_optarg
;
148 if (strcmp(argv
[prio_optind
- 1], "-c") == 0 ||
149 strcmp(argv
[prio_optind
- 1], "-i") == 0) {
152 * getopt() will return ? if either
153 * of these appear without an argument.
159 * We assume for now that any option that
160 * getopt() doesn't recognize (with the
161 * exception of c and i) is intended for a
162 * class specific subcommand. For now we also
163 * require that all class specific options
164 * take an argument (until we can get smarter
165 * about parsing our options).
178 if (dflag
|| sflag
|| eflag
|| cflag
|| iflag
|| csoptsflag
)
181 return (print_classlist());
184 if (lflag
|| sflag
|| eflag
|| cflag
|| csoptsflag
)
187 if (str2idtyp(idtypnm
, &idtype
) == -1)
188 fatalerr("%s: bad idtype %s\n", cmdpath
,
194 if (prio_optind
< argc
) {
195 idargc
= argc
- prio_optind
;
196 idargv
= &argv
[prio_optind
];
201 return (print_procs(idtype
, idargc
, idargv
));
204 if (lflag
|| dflag
|| eflag
)
207 if (str2idtyp(idtypnm
, &idtype
) == -1)
208 fatalerr("%s: bad idtype %s\n", cmdpath
,
217 if (prio_optind
< argc
) {
218 idargc
= argc
- prio_optind
;
219 idargv
= &argv
[prio_optind
];
224 set_procs(clname
, idtype
, idargc
, idargv
, argv
);
227 if (lflag
|| dflag
|| sflag
|| iflag
)
233 if (prio_optind
>= argc
)
236 exec_cmd(clname
, argv
);
247 * Print the heading for the class list and execute the class
248 * specific sub-command with the -l option for each configured class.
251 print_classlist(void)
256 static char subcmdpath
[128];
262 * No special privileges required for this operation.
263 * Set the effective UID back to the real UID.
265 if (setuid(getuid()) == -1)
266 fatalerr("%s: Can't set effective UID back to real UID\n",
269 if ((nclass
= priocntl(0, 0, PC_GETCLINFO
, NULL
)) == -1)
270 fatalerr("%s: Can't get number of configured classes, priocntl"
271 " system call failed with errno %d\n", cmdpath
, errno
);
273 (void) printf("CONFIGURED CLASSES\n==================\n\n");
274 (void) printf("SYS (System Class)\n");
275 for (cid
= 1; cid
< nclass
; cid
++) {
277 (void) fflush(stdout
);
279 if (priocntl(0, 0, PC_GETCLINFO
, (caddr_t
)&pcinfo
) == -1)
280 fatalerr("%s: can't get class name (class ID = %ld)\n",
282 if (snprintf(subcmdpath
, sizeof (subcmdpath
), "%s/%s/%s%s",
283 CLASSPATH
, pcinfo
.pc_clname
, pcinfo
.pc_clname
, basenm
) >=
285 fatalerr("%s: can't generate %s specific subcommand\n",
286 cmdpath
, pcinfo
.pc_clname
);
287 if ((pid
= fork()) == 0) {
288 (void) execl(subcmdpath
, subcmdpath
, "-l", (char *)0);
289 (void) printf("%s\n", pcinfo
.pc_clname
);
290 fatalerr("\tCan't execute %s specific subcommand\n",
292 } else if (pid
== (pid_t
)-1) {
293 (void) printf("%s\n", pcinfo
.pc_clname
);
294 (void) fprintf(stderr
,
295 "Can't execute %s specific subcommand)\n",
299 (void) wait(&status
);
310 * For each class represented within the set of processes specified by
311 * idtype/idargv, print_procs() executes the class specific sub-command
312 * with the -d option. We pipe to each sub-command a list of pids in
313 * the set belonging to that class.
316 print_procs(idtype_t idtype
, int idargc
, char *idargv
[])
327 FILE *pipe_to_subcmd
;
333 * Build a list of ids eliminating any duplicates in idargv.
335 if (idtype
== P_ALL
) {
337 * No idlist should be specified. If one is specified,
341 } else if (idargc
== 0) {
344 * No ids supplied by user; use current id.
346 if (getmyid(idtype
, &idlist
[0]) == -1)
347 fatalerr("%s: Can't get ID for current process,"
348 " idtype = %d\n", cmdpath
, idtype
);
352 for (i
= 0; i
< idargc
&& nids
< NIDS
; i
++) {
353 if (idtype
== P_CID
) {
354 if ((id
= clname2cid(idargv
[i
])) == -1) {
355 (void) fprintf(stderr
, "%s: Invalid or"
356 " unconfigured class %s in idlist"
357 " - ignored\n", cmdpath
, idargv
[i
]);
361 id
= (id_t
)str2num(idargv
[i
], INT_MIN
, INT_MAX
);
363 (void) fprintf(stderr
,
364 "%s: Invalid id \"%s\"\n",
372 * lsearch(3C) adds ids to the idlist,
373 * eliminating duplicates.
375 (void) lsearch((void *)&id
, (void *)idlist
,
376 (size_t *)&nids
, sizeof (id
), (int (*)())idcompar
);
380 if ((nclass
= priocntl(0, 0, PC_GETCLINFO
, NULL
)) == -1)
381 fatalerr("%s: Can't get number of configured classes, priocntl"
382 " system call failed with errno %d\n", cmdpath
, errno
);
384 if ((clpids
= (classpids_t
*)malloc(sizeof (classpids_t
) * nclass
)) ==
386 fatalerr("%s: Can't allocate memory for clpids.\n", cmdpath
);
388 for (cid
= 1; cid
< nclass
; cid
++) {
390 if (priocntl(0, 0, PC_GETCLINFO
, (caddr_t
)&pcinfo
) == -1)
391 fatalerr("%s: Can't get class name, cid = %ld\n",
394 (void) strncpy(clpids
[cid
].clp_clname
, pcinfo
.pc_clname
,
398 * The memory allocation for the pidlist uses realloc().
399 * A realloc() call is required, when "clp_npids" is
400 * equal to "clp_pidlistsz".
402 clpids
[cid
].clp_pidlist
= (pid_t
*)NULL
;
403 clpids
[cid
].clp_pidlistsz
= 0;
404 clpids
[cid
].clp_npids
= 0;
410 ids2pids(idtype
, idlist
, nids
, clpids
, nclass
);
413 * No need for special privileges any more.
414 * Set the effective UID back to the real UID.
416 if (setuid(getuid()) == -1)
417 fatalerr("%s: Can't set effective UID back to real UID\n",
421 for (cid
= 1; cid
< nclass
; cid
++) {
422 if (clpids
[cid
].clp_npids
== 0)
426 if (snprintf(subcmd
, sizeof (subcmd
), "%s/%s/%s%s -d",
427 CLASSPATH
, clpids
[cid
].clp_clname
, clpids
[cid
].clp_clname
,
428 basenm
) >= sizeof (subcmd
)) {
429 (void) fprintf(stderr
,
430 "Can't generate %s specific subcommand\n",
431 clpids
[cid
].clp_clname
);
433 free(clpids
[cid
].clp_pidlist
);
436 if ((pipe_to_subcmd
= popen(subcmd
, "w")) == NULL
) {
437 (void) printf("%s\n", clpids
[cid
].clp_clname
);
438 (void) fprintf(stderr
,
439 "Can't execute %s specific subcommand\n",
440 clpids
[cid
].clp_clname
);
442 free(clpids
[cid
].clp_pidlist
);
445 (void) fwrite(clpids
[cid
].clp_pidlist
, sizeof (pid_t
),
446 clpids
[cid
].clp_npids
, pipe_to_subcmd
);
447 if (pclose(pipe_to_subcmd
))
450 free(clpids
[cid
].clp_pidlist
);
456 fatalerr("%s: Process(es) not found.\n", cmdpath
);
463 * Execute the appropriate class specific sub-command with the arguments
464 * pointed to by subcmdargv. If the user specified a class we simply
465 * exec the sub-command for that class. If no class was specified we
466 * verify that the processes in the set specified by idtype/idargv are
467 * all in the same class and then execute the sub-command for that class.
470 set_procs(clname
, idtype
, idargc
, idargv
, subcmdargv
)
477 char idstr
[PC_IDTYPNMSZ
];
478 char myidstr
[PC_IDTYPNMSZ
];
479 char clnmbuf
[PC_CLNMSZ
];
481 static psinfo_t prinfo
;
482 static prcred_t prcred
;
484 struct dirent
*dentp
;
485 static char pname
[100];
489 static char subcmdpath
[128];
494 if (clname
== NULL
&& idtype
== P_PID
&& idargc
<= 1) {
497 * No class specified by user but only one process
498 * in specified set. Get the class the easy way.
501 if (priocntl(P_PID
, P_MYID
, PC_GETXPARMS
, NULL
,
502 PC_KY_CLNAME
, clnmbuf
, 0) == -1)
504 fatalerr("%s: Process not found.\n",
507 fatalerr("%s: Can't get class of"
508 " current process\npriocntl"
509 " system call failed with"
510 " errno %d\n", cmdpath
, errno
);
513 id
= (id_t
)str2num(idargv
[0], INT_MIN
, INT_MAX
);
515 fatalerr("%s: Invalid id \"%s\"\n", cmdpath
,
518 if (priocntl(P_PID
, id
, PC_GETXPARMS
,
519 NULL
, PC_KY_CLNAME
, clnmbuf
, 0) == -1)
521 fatalerr("%s: Process not found.\n",
524 fatalerr("%s: Can't get class of "
525 " specified process\npriocntl"
526 " system call failed with"
527 " errno %d\n", cmdpath
, errno
);
531 } else if (clname
== NULL
) {
534 * No class specified by user and potentially more
535 * than one process in specified set. Verify that
536 * all procs in set are in the same class.
538 if (idargc
== 0 && idtype
!= P_ALL
) {
541 * No ids supplied by user; use current id.
543 if (getmyidstr(idtype
, myidstr
) == -1)
544 fatalerr("%s: Can't get ID string for current"
545 " process, idtype = %d\n", cmdpath
, idtype
);
547 if ((dirp
= opendir(procdir
)) == NULL
)
548 fatalerr("%s: Can't open PROC directory %s\n",
551 while ((dentp
= readdir(dirp
)) != NULL
) {
552 if (dentp
->d_name
[0] == '.') /* skip . and .. */
555 len
= snprintf(pname
, sizeof (pname
), "%s/%s/",
556 procdir
, dentp
->d_name
);
557 /* Really max(sizeof ("psinfo"), sizeof ("cred")) */
558 if (len
+ sizeof ("psinfo") > sizeof (pname
)) {
559 (void) fprintf(stderr
,
560 "%s: skipping %s, name too long.\n",
561 cmdpath
, dentp
->d_name
);
566 (void) strcpy(fname
, "psinfo");
567 if ((procfd
= open(pname
, O_RDONLY
)) < 0)
570 if (read(procfd
, &prinfo
, sizeof (prinfo
)) !=
573 (void) close(procfd
);
574 if (saverr
== EAGAIN
)
576 if (saverr
!= ENOENT
) {
577 (void) fprintf(stderr
,
578 "%s: Can't get process info for"
579 " %s\n", cmdpath
, pname
);
583 (void) close(procfd
);
585 if (idtype
== P_UID
|| idtype
== P_GID
) {
586 (void) strcpy(fname
, "cred");
587 if ((procfd
= open(pname
, O_RDONLY
)) < 0 ||
588 read(procfd
, &prcred
, sizeof (prcred
)) !=
592 (void) close(procfd
);
593 if (saverr
== EAGAIN
)
595 if (saverr
!= ENOENT
) {
596 (void) fprintf(stderr
,
597 "%s: Can't get process"
598 " credentials for %s\n",
603 (void) close(procfd
);
606 if (prinfo
.pr_lwp
.pr_state
== 0 || prinfo
.pr_nlwp
== 0)
613 itoa((long)prinfo
.pr_pid
, idstr
);
614 procinset
= idmatch(idstr
, myidstr
,
619 itoa((long)prinfo
.pr_ppid
, idstr
);
620 procinset
= idmatch(idstr
, myidstr
,
625 itoa((long)prinfo
.pr_pgid
, idstr
);
626 procinset
= idmatch(idstr
, myidstr
,
631 itoa((long)prinfo
.pr_sid
, idstr
);
632 procinset
= idmatch(idstr
, myidstr
,
637 procinset
= idmatch(prinfo
.pr_lwp
.pr_clname
,
638 myidstr
, idargc
, idargv
);
642 itoa((long)prcred
.pr_euid
, idstr
);
643 procinset
= idmatch(idstr
, myidstr
,
648 itoa((long)prcred
.pr_egid
, idstr
);
649 procinset
= idmatch(idstr
, myidstr
,
654 itoa((long)prinfo
.pr_projid
, idstr
);
655 procinset
= idmatch(idstr
, myidstr
,
660 itoa((long)prinfo
.pr_taskid
, idstr
);
661 procinset
= idmatch(idstr
, myidstr
,
666 itoa((long)prinfo
.pr_zoneid
, idstr
);
667 procinset
= idmatch(idstr
, myidstr
,
672 itoa((long)prinfo
.pr_contract
, idstr
);
673 procinset
= idmatch(idstr
, myidstr
,
682 fatalerr("%s: Bad idtype %d in set_procs()\n",
685 if (procinset
== B_TRUE
) {
686 if (clname
== NULL
) {
689 * First proc found in set.
691 (void) strcpy(clnmbuf
,
692 prinfo
.pr_lwp
.pr_clname
);
694 } else if (strcmp(clname
,
695 prinfo
.pr_lwp
.pr_clname
) != 0) {
696 fatalerr("%s: Specified processes"
697 " from different classes.\n",
702 (void) closedir(dirp
);
704 fatalerr("%s: Process(es) not found.\n", cmdpath
);
708 * User specified class. Check it for validity.
710 (void) strcpy(pcinfo
.pc_clname
, clname
);
711 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) == -1)
712 fatalerr("%s: Invalid or unconfigured class %s\n",
717 * No need for special privileges any more.
718 * Set the effective UID back to the real UID.
720 if (setuid(getuid()) == -1)
721 fatalerr("%s: Can't set effective UID back to real UID\n",
724 if (snprintf(subcmdpath
, sizeof (subcmdpath
), "%s/%s/%s%s",
725 CLASSPATH
, clname
, clname
, basenm
) >= sizeof (subcmdpath
))
726 fatalerr("%s: can't generate %s specific subcommand\n",
729 subcmdargv
[0] = subcmdpath
;
730 (void) execv(subcmdpath
, subcmdargv
);
731 fatalerr("%s: Can't execute %s sub-command\n", cmdpath
, clname
);
736 * Execute the appropriate class specific sub-command with the arguments
737 * pointed to by subcmdargv. If the user specified a class we simply
738 * exec the sub-command for that class. If no class was specified we
739 * execute the sub-command for our own current class.
742 exec_cmd(clname
, subcmdargv
)
747 char clnmbuf
[PC_CLNMSZ
];
748 char subcmdpath
[128];
751 * No special privileges required for this operation.
752 * Set the effective UID back to the real UID.
754 if (setuid(getuid()) == -1)
755 fatalerr("%s: Can't set effective UID back to real UID\n",
758 if (clname
== NULL
) {
759 if (priocntl(P_PID
, P_MYID
, PC_GETXPARMS
, NULL
,
760 PC_KY_CLNAME
, clnmbuf
, 0) == -1)
761 fatalerr("%s: Can't get class name of current process\n"
762 "priocntl system call failed with errno %d\n",
769 * User specified class. Check it for validity.
771 (void) strcpy(pcinfo
.pc_clname
, clname
);
772 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) == -1)
773 fatalerr("%s: Invalid or unconfigured class %s\n",
777 if (snprintf(subcmdpath
, sizeof (subcmdpath
), "%s/%s/%s%s",
778 CLASSPATH
, clname
, clname
, basenm
) >= sizeof (subcmdpath
))
779 fatalerr("%s: can't generate %s specific subcommand\n",
781 subcmdargv
[0] = subcmdpath
;
782 (void) execv(subcmdpath
, subcmdargv
);
783 fatalerr("%s: Can't execute %s sub-command\n", cmdpath
, clname
);
788 * Fill in the classpids structures in the array pointed to by clpids
789 * with pids for the processes in the set specified by idtype/idlist.
790 * We read the /proc/<pid>/psinfo file to get the necessary process
794 ids2pids(idtype
, idlist
, nids
, clpids
, nclass
)
801 static psinfo_t prinfo
;
802 static prcred_t prcred
;
804 struct dirent
*dentp
;
813 if ((dirp
= opendir(procdir
)) == NULL
)
814 fatalerr("%s: Can't open PROC directory %s\n",
817 while ((dentp
= readdir(dirp
)) != NULL
) {
818 if (dentp
->d_name
[0] == '.') /* skip . and .. */
821 len
= snprintf(pname
, sizeof (pname
), "%s/%s/",
822 procdir
, dentp
->d_name
);
823 /* Really max(sizeof ("psinfo"), sizeof ("cred")) */
824 if (len
+ sizeof ("psinfo") > sizeof (pname
)) {
825 (void) fprintf(stderr
,
826 "%s: skipping %s, name too long.\n",
827 cmdpath
, dentp
->d_name
);
832 (void) strcpy(fname
, "psinfo");
833 if ((procfd
= open(pname
, O_RDONLY
)) < 0)
835 if (read(procfd
, &prinfo
, sizeof (prinfo
)) != sizeof (prinfo
)) {
837 (void) close(procfd
);
838 if (saverr
== EAGAIN
)
840 if (saverr
!= ENOENT
) {
841 (void) fprintf(stderr
,
842 "%s: Can't get process info for %s\n",
847 (void) close(procfd
);
849 if (idtype
== P_UID
|| idtype
== P_GID
) {
850 (void) strcpy(fname
, "cred");
851 if ((procfd
= open(pname
, O_RDONLY
)) < 0 ||
852 read(procfd
, &prcred
, sizeof (prcred
)) !=
855 (void) close(procfd
);
856 if (saverr
== EAGAIN
)
858 if (saverr
!= ENOENT
) {
859 (void) fprintf(stderr
,
860 "%s: Can't get process credentials"
866 (void) close(procfd
);
869 if (prinfo
.pr_lwp
.pr_state
== 0 || prinfo
.pr_nlwp
== 0)
875 for (i
= 0; i
< nids
; i
++) {
876 if (idlist
[i
] == (id_t
)prinfo
.pr_pid
)
877 add_pid_tolist(clpids
, nclass
,
878 prinfo
.pr_lwp
.pr_clname
,
884 for (i
= 0; i
< nids
; i
++) {
885 if (idlist
[i
] == (id_t
)prinfo
.pr_ppid
)
886 add_pid_tolist(clpids
, nclass
,
887 prinfo
.pr_lwp
.pr_clname
,
893 for (i
= 0; i
< nids
; i
++) {
894 if (idlist
[i
] == (id_t
)prinfo
.pr_pgid
)
895 add_pid_tolist(clpids
, nclass
,
896 prinfo
.pr_lwp
.pr_clname
,
902 for (i
= 0; i
< nids
; i
++) {
903 if (idlist
[i
] == (id_t
)prinfo
.pr_sid
)
904 add_pid_tolist(clpids
, nclass
,
905 prinfo
.pr_lwp
.pr_clname
,
911 for (i
= 0; i
< nids
; i
++) {
912 clname
= clpids
[idlist
[i
]].clp_clname
;
914 prinfo
.pr_lwp
.pr_clname
) == 0)
915 add_pid_tolist(clpids
, nclass
,
916 prinfo
.pr_lwp
.pr_clname
,
922 for (i
= 0; i
< nids
; i
++) {
923 if (idlist
[i
] == (id_t
)prcred
.pr_euid
)
924 add_pid_tolist(clpids
, nclass
,
925 prinfo
.pr_lwp
.pr_clname
,
931 for (i
= 0; i
< nids
; i
++) {
932 if (idlist
[i
] == (id_t
)prcred
.pr_egid
)
933 add_pid_tolist(clpids
, nclass
,
934 prinfo
.pr_lwp
.pr_clname
,
940 for (i
= 0; i
< nids
; i
++) {
941 if (idlist
[i
] == (id_t
)prinfo
.pr_projid
)
942 add_pid_tolist(clpids
, nclass
,
943 prinfo
.pr_lwp
.pr_clname
,
949 for (i
= 0; i
< nids
; i
++) {
950 if (idlist
[i
] == (id_t
)prinfo
.pr_taskid
)
951 add_pid_tolist(clpids
, nclass
,
952 prinfo
.pr_lwp
.pr_clname
,
958 for (i
= 0; i
< nids
; i
++) {
959 if (idlist
[i
] == (id_t
)prinfo
.pr_zoneid
)
960 add_pid_tolist(clpids
, nclass
,
961 prinfo
.pr_lwp
.pr_clname
,
967 for (i
= 0; i
< nids
; i
++) {
968 if (idlist
[i
] == (id_t
)prinfo
.pr_contract
)
969 add_pid_tolist(clpids
, nclass
,
970 prinfo
.pr_lwp
.pr_clname
,
976 add_pid_tolist(clpids
, nclass
, prinfo
.pr_lwp
.pr_clname
,
981 fatalerr("%s: Bad idtype %d in ids2pids()\n",
985 (void) closedir(dirp
);
990 * Search the array pointed to by clpids for the classpids
991 * structure corresponding to clname and add pid to its
995 add_pid_tolist(clpids
, nclass
, clname
, pid
)
1003 for (clp
= clpids
; clp
!= &clpids
[nclass
]; clp
++) {
1004 if (strcmp(clp
->clp_clname
, clname
) == 0) {
1005 if (clp
->clp_npids
== clp
->clp_pidlistsz
)
1006 increase_pidlist(clp
);
1008 (clp
->clp_pidlist
)[clp
->clp_npids
] = pid
;
1017 increase_pidlist(classpids_t
*clp
)
1019 if ((clp
->clp_pidlist
= realloc(clp
->clp_pidlist
,
1020 (clp
->clp_pidlistsz
+ NPIDS
) * sizeof (pid_t
))) == NULL
)
1022 * The pidlist is filled up and we cannot increase the size.
1024 fatalerr("%s: Can't allocate memory for pidlist.\n", cmdpath
);
1026 clp
->clp_pidlistsz
+= NPIDS
;
1031 * Compare id strings for equality. If idargv contains ids
1032 * (idargc > 0) compare idstr to each id in idargv, otherwise
1033 * just compare to curidstr.
1036 idmatch(idstr
, curidstr
, idargc
, idargv
)
1045 if (strcmp(curidstr
, idstr
) == 0)
1048 for (i
= 0; i
< idargc
; i
++) {
1049 if (strcmp(idargv
[i
], idstr
) == 0)
1057 * This is a copy of the getopt() function found in libc:getopt.c. A separate
1058 * copy is required to fix the bug id #1114636. To fix the problem we need to
1059 * reset the _sp to 1. Since _sp in libc:getopt() is not exposed, a copy of
1060 * the getopt() is kept so that prio_sp can be reset to 1.
1064 prio_getopt(argc
, argv
, opts
)
1067 char *const *argv
, *opts
;
1076 if (prio_optind
>= argc
||
1077 argv
[prio_optind
][0] != '-' || argv
[prio_optind
][1] == '\0')
1079 else if (strcmp(argv
[prio_optind
], "--") == NULL
) {
1083 prio_optopt
= c
= (unsigned char)argv
[prio_optind
][prio_sp
];
1084 if (c
== ':' || (cp
= strchr(opts
, c
)) == NULL
) {
1085 if (argv
[prio_optind
][++prio_sp
] == '\0') {
1092 if (argv
[prio_optind
][prio_sp
+1] != '\0')
1093 prio_optarg
= &argv
[prio_optind
++][prio_sp
+1];
1094 else if (++prio_optind
>= argc
) {
1098 prio_optarg
= argv
[prio_optind
++];
1101 if (argv
[prio_optind
][++prio_sp
] == '\0') {