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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
37 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/procset.h>
42 #include <sys/priocntl.h>
52 * This file contains the code implementing the class independent part
53 * of the priocntl command. Most of the useful work for the priocntl
54 * command is done by the class specific sub-commands, the code for
55 * which is elsewhere. The class independent part of the command is
56 * responsible for executing the appropriate class specific sub-commands
57 * and providing any necessary input to the sub-commands.
58 * Code in this file should never assume any knowledge of any specific
59 * scheduler class (other than the SYS class).
62 #define CLASSPATH "/usr/lib/class"
64 typedef struct classpids
{
65 char clp_clname
[PC_CLNMSZ
];
72 "usage: priocntl -l\n\
73 priocntl -d [-i idtype] [idlist]\n\
74 priocntl -s [-c class] [c.s.o.] [-i idtype] [idlist]\n\
75 priocntl -e [-c class] [c.s.o.] command [argument(s)]\n";
77 static char basenm
[BASENMSZ
];
78 static char cmdpath
[MAXPATHLEN
];
80 static char *procdir
= "/proc";
82 static int print_classlist(void);
83 static void set_procs(char *, idtype_t
, int, char **, char **);
84 static void exec_cmd(char *, char **);
85 static int print_procs(idtype_t
, int, char *[]);
86 static void ids2pids(idtype_t
, id_t
*, int, classpids_t
*, int);
87 static void add_pid_tolist(classpids_t
*, int, char *, pid_t
);
88 static void increase_pidlist(classpids_t
*);
89 static boolean_t
idmatch(char *, char *, int, char **);
92 * These variables are defined to be used in prio_getopt() below.
94 static int prio_getopt();
95 /* LINTED static unused */
96 static int prio_optopt
= 0;
97 static char *prio_optarg
= 0;
98 static int prio_optind
= 1;
99 static int prio_sp
= 1;
102 main(int argc
, char *argv
[])
105 int lflag
, dflag
, sflag
, eflag
, cflag
, iflag
, csoptsflag
;
112 (void) strlcpy(cmdpath
, argv
[0], MAXPATHLEN
);
113 (void) strlcpy(basenm
, basename(argv
[0]), BASENMSZ
);
114 lflag
= dflag
= sflag
= eflag
= cflag
= iflag
= csoptsflag
= 0;
115 while ((c
= prio_getopt(argc
, argv
, "ldsec:i:")) != -1) {
137 clname
= prio_optarg
;
142 idtypnm
= prio_optarg
;
146 if (strcmp(argv
[prio_optind
- 1], "-c") == 0 ||
147 strcmp(argv
[prio_optind
- 1], "-i") == 0) {
150 * getopt() will return ? if either
151 * of these appear without an argument.
157 * We assume for now that any option that
158 * getopt() doesn't recognize (with the
159 * exception of c and i) is intended for a
160 * class specific subcommand. For now we also
161 * require that all class specific options
162 * take an argument (until we can get smarter
163 * about parsing our options).
176 if (dflag
|| sflag
|| eflag
|| cflag
|| iflag
|| csoptsflag
)
179 return (print_classlist());
182 if (lflag
|| sflag
|| eflag
|| cflag
|| csoptsflag
)
185 if (str2idtyp(idtypnm
, &idtype
) == -1)
186 fatalerr("%s: bad idtype %s\n", cmdpath
,
192 if (prio_optind
< argc
) {
193 idargc
= argc
- prio_optind
;
194 idargv
= &argv
[prio_optind
];
199 return (print_procs(idtype
, idargc
, idargv
));
202 if (lflag
|| dflag
|| eflag
)
205 if (str2idtyp(idtypnm
, &idtype
) == -1)
206 fatalerr("%s: bad idtype %s\n", cmdpath
,
215 if (prio_optind
< argc
) {
216 idargc
= argc
- prio_optind
;
217 idargv
= &argv
[prio_optind
];
222 set_procs(clname
, idtype
, idargc
, idargv
, argv
);
225 if (lflag
|| dflag
|| sflag
|| iflag
)
231 if (prio_optind
>= argc
)
234 exec_cmd(clname
, argv
);
245 * Print the heading for the class list and execute the class
246 * specific sub-command with the -l option for each configured class.
249 print_classlist(void)
254 static char subcmdpath
[128];
260 * No special privileges required for this operation.
261 * Set the effective UID back to the real UID.
263 if (setuid(getuid()) == -1)
264 fatalerr("%s: Can't set effective UID back to real UID\n",
267 if ((nclass
= priocntl(0, 0, PC_GETCLINFO
, NULL
)) == -1)
268 fatalerr("%s: Can't get number of configured classes, priocntl"
269 " system call failed with errno %d\n", cmdpath
, errno
);
271 (void) printf("CONFIGURED CLASSES\n==================\n\n");
272 (void) printf("SYS (System Class)\n");
273 for (cid
= 1; cid
< nclass
; cid
++) {
275 (void) fflush(stdout
);
277 if (priocntl(0, 0, PC_GETCLINFO
, (caddr_t
)&pcinfo
) == -1)
278 fatalerr("%s: can't get class name (class ID = %ld)\n",
280 if (snprintf(subcmdpath
, sizeof (subcmdpath
), "%s/%s/%s%s",
281 CLASSPATH
, pcinfo
.pc_clname
, pcinfo
.pc_clname
, basenm
) >=
283 fatalerr("%s: can't generate %s specific subcommand\n",
284 cmdpath
, pcinfo
.pc_clname
);
285 if ((pid
= fork()) == 0) {
286 (void) execl(subcmdpath
, subcmdpath
, "-l", (char *)0);
287 (void) printf("%s\n", pcinfo
.pc_clname
);
288 fatalerr("\tCan't execute %s specific subcommand\n",
290 } else if (pid
== (pid_t
)-1) {
291 (void) printf("%s\n", pcinfo
.pc_clname
);
292 (void) fprintf(stderr
,
293 "Can't execute %s specific subcommand)\n",
297 (void) wait(&status
);
308 * For each class represented within the set of processes specified by
309 * idtype/idargv, print_procs() executes the class specific sub-command
310 * with the -d option. We pipe to each sub-command a list of pids in
311 * the set belonging to that class.
314 print_procs(idtype_t idtype
, int idargc
, char *idargv
[])
325 FILE *pipe_to_subcmd
;
331 * Build a list of ids eliminating any duplicates in idargv.
333 if (idtype
== P_ALL
) {
335 * No idlist should be specified. If one is specified,
339 } else if (idargc
== 0) {
342 * No ids supplied by user; use current id.
344 if (getmyid(idtype
, &idlist
[0]) == -1)
345 fatalerr("%s: Can't get ID for current process,"
346 " idtype = %d\n", cmdpath
, idtype
);
350 for (i
= 0; i
< idargc
&& nids
< NIDS
; i
++) {
351 if (idtype
== P_CID
) {
352 if ((id
= clname2cid(idargv
[i
])) == -1) {
353 (void) fprintf(stderr
, "%s: Invalid or"
354 " unconfigured class %s in idlist"
355 " - ignored\n", cmdpath
, idargv
[i
]);
359 id
= (id_t
)str2num(idargv
[i
], INT_MIN
, INT_MAX
);
361 (void) fprintf(stderr
,
362 "%s: Invalid id \"%s\"\n",
370 * lsearch(3C) adds ids to the idlist,
371 * eliminating duplicates.
373 (void) lsearch((void *)&id
, (void *)idlist
,
374 (size_t *)&nids
, sizeof (id
), (int (*)())idcompar
);
378 if ((nclass
= priocntl(0, 0, PC_GETCLINFO
, NULL
)) == -1)
379 fatalerr("%s: Can't get number of configured classes, priocntl"
380 " system call failed with errno %d\n", cmdpath
, errno
);
382 if ((clpids
= (classpids_t
*)malloc(sizeof (classpids_t
) * nclass
)) ==
384 fatalerr("%s: Can't allocate memory for clpids.\n", cmdpath
);
386 for (cid
= 1; cid
< nclass
; cid
++) {
388 if (priocntl(0, 0, PC_GETCLINFO
, (caddr_t
)&pcinfo
) == -1)
389 fatalerr("%s: Can't get class name, cid = %ld\n",
392 (void) strncpy(clpids
[cid
].clp_clname
, pcinfo
.pc_clname
,
396 * The memory allocation for the pidlist uses realloc().
397 * A realloc() call is required, when "clp_npids" is
398 * equal to "clp_pidlistsz".
400 clpids
[cid
].clp_pidlist
= (pid_t
*)NULL
;
401 clpids
[cid
].clp_pidlistsz
= 0;
402 clpids
[cid
].clp_npids
= 0;
408 ids2pids(idtype
, idlist
, nids
, clpids
, nclass
);
411 * No need for special privileges any more.
412 * Set the effective UID back to the real UID.
414 if (setuid(getuid()) == -1)
415 fatalerr("%s: Can't set effective UID back to real UID\n",
419 for (cid
= 1; cid
< nclass
; cid
++) {
420 if (clpids
[cid
].clp_npids
== 0)
424 if (snprintf(subcmd
, sizeof (subcmd
), "%s/%s/%s%s -d",
425 CLASSPATH
, clpids
[cid
].clp_clname
, clpids
[cid
].clp_clname
,
426 basenm
) >= sizeof (subcmd
)) {
427 (void) fprintf(stderr
,
428 "Can't generate %s specific subcommand\n",
429 clpids
[cid
].clp_clname
);
431 free(clpids
[cid
].clp_pidlist
);
434 if ((pipe_to_subcmd
= popen(subcmd
, "w")) == NULL
) {
435 (void) printf("%s\n", clpids
[cid
].clp_clname
);
436 (void) fprintf(stderr
,
437 "Can't execute %s specific subcommand\n",
438 clpids
[cid
].clp_clname
);
440 free(clpids
[cid
].clp_pidlist
);
443 (void) fwrite(clpids
[cid
].clp_pidlist
, sizeof (pid_t
),
444 clpids
[cid
].clp_npids
, pipe_to_subcmd
);
445 if (pclose(pipe_to_subcmd
))
448 free(clpids
[cid
].clp_pidlist
);
454 fatalerr("%s: Process(es) not found.\n", cmdpath
);
461 * Execute the appropriate class specific sub-command with the arguments
462 * pointed to by subcmdargv. If the user specified a class we simply
463 * exec the sub-command for that class. If no class was specified we
464 * verify that the processes in the set specified by idtype/idargv are
465 * all in the same class and then execute the sub-command for that class.
468 set_procs(clname
, idtype
, idargc
, idargv
, subcmdargv
)
475 char idstr
[PC_IDTYPNMSZ
];
476 char myidstr
[PC_IDTYPNMSZ
];
477 char clnmbuf
[PC_CLNMSZ
];
479 static psinfo_t prinfo
;
480 static prcred_t prcred
;
482 struct dirent
*dentp
;
483 static char pname
[100];
487 static char subcmdpath
[128];
492 if (clname
== NULL
&& idtype
== P_PID
&& idargc
<= 1) {
495 * No class specified by user but only one process
496 * in specified set. Get the class the easy way.
499 if (priocntl(P_PID
, P_MYID
, PC_GETXPARMS
, NULL
,
500 PC_KY_CLNAME
, clnmbuf
, 0) == -1)
502 fatalerr("%s: Process not found.\n",
505 fatalerr("%s: Can't get class of"
506 " current process\npriocntl"
507 " system call failed with"
508 " errno %d\n", cmdpath
, errno
);
511 id
= (id_t
)str2num(idargv
[0], INT_MIN
, INT_MAX
);
513 fatalerr("%s: Invalid id \"%s\"\n", cmdpath
,
516 if (priocntl(P_PID
, id
, PC_GETXPARMS
,
517 NULL
, PC_KY_CLNAME
, clnmbuf
, 0) == -1)
519 fatalerr("%s: Process not found.\n",
522 fatalerr("%s: Can't get class of "
523 " specified process\npriocntl"
524 " system call failed with"
525 " errno %d\n", cmdpath
, errno
);
529 } else if (clname
== NULL
) {
532 * No class specified by user and potentially more
533 * than one process in specified set. Verify that
534 * all procs in set are in the same class.
536 if (idargc
== 0 && idtype
!= P_ALL
) {
539 * No ids supplied by user; use current id.
541 if (getmyidstr(idtype
, myidstr
) == -1)
542 fatalerr("%s: Can't get ID string for current"
543 " process, idtype = %d\n", cmdpath
, idtype
);
545 if ((dirp
= opendir(procdir
)) == NULL
)
546 fatalerr("%s: Can't open PROC directory %s\n",
549 while ((dentp
= readdir(dirp
)) != NULL
) {
550 if (dentp
->d_name
[0] == '.') /* skip . and .. */
553 len
= snprintf(pname
, sizeof (pname
), "%s/%s/",
554 procdir
, dentp
->d_name
);
555 /* Really max(sizeof ("psinfo"), sizeof ("cred")) */
556 if (len
+ sizeof ("psinfo") > sizeof (pname
)) {
557 (void) fprintf(stderr
,
558 "%s: skipping %s, name too long.\n",
559 cmdpath
, dentp
->d_name
);
564 (void) strcpy(fname
, "psinfo");
565 if ((procfd
= open(pname
, O_RDONLY
)) < 0)
568 if (read(procfd
, &prinfo
, sizeof (prinfo
)) !=
571 (void) close(procfd
);
572 if (saverr
== EAGAIN
)
574 if (saverr
!= ENOENT
) {
575 (void) fprintf(stderr
,
576 "%s: Can't get process info for"
577 " %s\n", cmdpath
, pname
);
581 (void) close(procfd
);
583 if (idtype
== P_UID
|| idtype
== P_GID
) {
584 (void) strcpy(fname
, "cred");
585 if ((procfd
= open(pname
, O_RDONLY
)) < 0 ||
586 read(procfd
, &prcred
, sizeof (prcred
)) !=
590 (void) close(procfd
);
591 if (saverr
== EAGAIN
)
593 if (saverr
!= ENOENT
) {
594 (void) fprintf(stderr
,
595 "%s: Can't get process"
596 " credentials for %s\n",
601 (void) close(procfd
);
604 if (prinfo
.pr_lwp
.pr_state
== 0 || prinfo
.pr_nlwp
== 0)
611 itoa((long)prinfo
.pr_pid
, idstr
);
612 procinset
= idmatch(idstr
, myidstr
,
617 itoa((long)prinfo
.pr_ppid
, idstr
);
618 procinset
= idmatch(idstr
, myidstr
,
623 itoa((long)prinfo
.pr_pgid
, idstr
);
624 procinset
= idmatch(idstr
, myidstr
,
629 itoa((long)prinfo
.pr_sid
, idstr
);
630 procinset
= idmatch(idstr
, myidstr
,
635 procinset
= idmatch(prinfo
.pr_lwp
.pr_clname
,
636 myidstr
, idargc
, idargv
);
640 itoa((long)prcred
.pr_euid
, idstr
);
641 procinset
= idmatch(idstr
, myidstr
,
646 itoa((long)prcred
.pr_egid
, idstr
);
647 procinset
= idmatch(idstr
, myidstr
,
652 itoa((long)prinfo
.pr_projid
, idstr
);
653 procinset
= idmatch(idstr
, myidstr
,
658 itoa((long)prinfo
.pr_taskid
, idstr
);
659 procinset
= idmatch(idstr
, myidstr
,
664 itoa((long)prinfo
.pr_zoneid
, idstr
);
665 procinset
= idmatch(idstr
, myidstr
,
670 itoa((long)prinfo
.pr_contract
, idstr
);
671 procinset
= idmatch(idstr
, myidstr
,
680 fatalerr("%s: Bad idtype %d in set_procs()\n",
683 if (procinset
== B_TRUE
) {
684 if (clname
== NULL
) {
687 * First proc found in set.
689 (void) strcpy(clnmbuf
,
690 prinfo
.pr_lwp
.pr_clname
);
692 } else if (strcmp(clname
,
693 prinfo
.pr_lwp
.pr_clname
) != 0) {
694 fatalerr("%s: Specified processes"
695 " from different classes.\n",
700 (void) closedir(dirp
);
702 fatalerr("%s: Process(es) not found.\n", cmdpath
);
706 * User specified class. Check it for validity.
708 (void) strcpy(pcinfo
.pc_clname
, clname
);
709 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) == -1)
710 fatalerr("%s: Invalid or unconfigured class %s\n",
715 * No need for special privileges any more.
716 * Set the effective UID back to the real UID.
718 if (setuid(getuid()) == -1)
719 fatalerr("%s: Can't set effective UID back to real UID\n",
722 if (snprintf(subcmdpath
, sizeof (subcmdpath
), "%s/%s/%s%s",
723 CLASSPATH
, clname
, clname
, basenm
) >= sizeof (subcmdpath
))
724 fatalerr("%s: can't generate %s specific subcommand\n",
727 subcmdargv
[0] = subcmdpath
;
728 (void) execv(subcmdpath
, subcmdargv
);
729 fatalerr("%s: Can't execute %s sub-command\n", cmdpath
, clname
);
734 * Execute the appropriate class specific sub-command with the arguments
735 * pointed to by subcmdargv. If the user specified a class we simply
736 * exec the sub-command for that class. If no class was specified we
737 * execute the sub-command for our own current class.
740 exec_cmd(clname
, subcmdargv
)
745 char clnmbuf
[PC_CLNMSZ
];
746 char subcmdpath
[128];
749 * No special privileges required for this operation.
750 * Set the effective UID back to the real UID.
752 if (setuid(getuid()) == -1)
753 fatalerr("%s: Can't set effective UID back to real UID\n",
756 if (clname
== NULL
) {
757 if (priocntl(P_PID
, P_MYID
, PC_GETXPARMS
, NULL
,
758 PC_KY_CLNAME
, clnmbuf
, 0) == -1)
759 fatalerr("%s: Can't get class name of current process\n"
760 "priocntl system call failed with errno %d\n",
767 * User specified class. Check it for validity.
769 (void) strcpy(pcinfo
.pc_clname
, clname
);
770 if (priocntl(0, 0, PC_GETCID
, (caddr_t
)&pcinfo
) == -1)
771 fatalerr("%s: Invalid or unconfigured class %s\n",
775 if (snprintf(subcmdpath
, sizeof (subcmdpath
), "%s/%s/%s%s",
776 CLASSPATH
, clname
, clname
, basenm
) >= sizeof (subcmdpath
))
777 fatalerr("%s: can't generate %s specific subcommand\n",
779 subcmdargv
[0] = subcmdpath
;
780 (void) execv(subcmdpath
, subcmdargv
);
781 fatalerr("%s: Can't execute %s sub-command\n", cmdpath
, clname
);
786 * Fill in the classpids structures in the array pointed to by clpids
787 * with pids for the processes in the set specified by idtype/idlist.
788 * We read the /proc/<pid>/psinfo file to get the necessary process
792 ids2pids(idtype
, idlist
, nids
, clpids
, nclass
)
799 static psinfo_t prinfo
;
800 static prcred_t prcred
;
802 struct dirent
*dentp
;
811 if ((dirp
= opendir(procdir
)) == NULL
)
812 fatalerr("%s: Can't open PROC directory %s\n",
815 while ((dentp
= readdir(dirp
)) != NULL
) {
816 if (dentp
->d_name
[0] == '.') /* skip . and .. */
819 len
= snprintf(pname
, sizeof (pname
), "%s/%s/",
820 procdir
, dentp
->d_name
);
821 /* Really max(sizeof ("psinfo"), sizeof ("cred")) */
822 if (len
+ sizeof ("psinfo") > sizeof (pname
)) {
823 (void) fprintf(stderr
,
824 "%s: skipping %s, name too long.\n",
825 cmdpath
, dentp
->d_name
);
830 (void) strcpy(fname
, "psinfo");
831 if ((procfd
= open(pname
, O_RDONLY
)) < 0)
833 if (read(procfd
, &prinfo
, sizeof (prinfo
)) != sizeof (prinfo
)) {
835 (void) close(procfd
);
836 if (saverr
== EAGAIN
)
838 if (saverr
!= ENOENT
) {
839 (void) fprintf(stderr
,
840 "%s: Can't get process info for %s\n",
845 (void) close(procfd
);
847 if (idtype
== P_UID
|| idtype
== P_GID
) {
848 (void) strcpy(fname
, "cred");
849 if ((procfd
= open(pname
, O_RDONLY
)) < 0 ||
850 read(procfd
, &prcred
, sizeof (prcred
)) !=
853 (void) close(procfd
);
854 if (saverr
== EAGAIN
)
856 if (saverr
!= ENOENT
) {
857 (void) fprintf(stderr
,
858 "%s: Can't get process credentials"
864 (void) close(procfd
);
867 if (prinfo
.pr_lwp
.pr_state
== 0 || prinfo
.pr_nlwp
== 0)
873 for (i
= 0; i
< nids
; i
++) {
874 if (idlist
[i
] == (id_t
)prinfo
.pr_pid
)
875 add_pid_tolist(clpids
, nclass
,
876 prinfo
.pr_lwp
.pr_clname
,
882 for (i
= 0; i
< nids
; i
++) {
883 if (idlist
[i
] == (id_t
)prinfo
.pr_ppid
)
884 add_pid_tolist(clpids
, nclass
,
885 prinfo
.pr_lwp
.pr_clname
,
891 for (i
= 0; i
< nids
; i
++) {
892 if (idlist
[i
] == (id_t
)prinfo
.pr_pgid
)
893 add_pid_tolist(clpids
, nclass
,
894 prinfo
.pr_lwp
.pr_clname
,
900 for (i
= 0; i
< nids
; i
++) {
901 if (idlist
[i
] == (id_t
)prinfo
.pr_sid
)
902 add_pid_tolist(clpids
, nclass
,
903 prinfo
.pr_lwp
.pr_clname
,
909 for (i
= 0; i
< nids
; i
++) {
910 clname
= clpids
[idlist
[i
]].clp_clname
;
912 prinfo
.pr_lwp
.pr_clname
) == 0)
913 add_pid_tolist(clpids
, nclass
,
914 prinfo
.pr_lwp
.pr_clname
,
920 for (i
= 0; i
< nids
; i
++) {
921 if (idlist
[i
] == (id_t
)prcred
.pr_euid
)
922 add_pid_tolist(clpids
, nclass
,
923 prinfo
.pr_lwp
.pr_clname
,
929 for (i
= 0; i
< nids
; i
++) {
930 if (idlist
[i
] == (id_t
)prcred
.pr_egid
)
931 add_pid_tolist(clpids
, nclass
,
932 prinfo
.pr_lwp
.pr_clname
,
938 for (i
= 0; i
< nids
; i
++) {
939 if (idlist
[i
] == (id_t
)prinfo
.pr_projid
)
940 add_pid_tolist(clpids
, nclass
,
941 prinfo
.pr_lwp
.pr_clname
,
947 for (i
= 0; i
< nids
; i
++) {
948 if (idlist
[i
] == (id_t
)prinfo
.pr_taskid
)
949 add_pid_tolist(clpids
, nclass
,
950 prinfo
.pr_lwp
.pr_clname
,
956 for (i
= 0; i
< nids
; i
++) {
957 if (idlist
[i
] == (id_t
)prinfo
.pr_zoneid
)
958 add_pid_tolist(clpids
, nclass
,
959 prinfo
.pr_lwp
.pr_clname
,
965 for (i
= 0; i
< nids
; i
++) {
966 if (idlist
[i
] == (id_t
)prinfo
.pr_contract
)
967 add_pid_tolist(clpids
, nclass
,
968 prinfo
.pr_lwp
.pr_clname
,
974 add_pid_tolist(clpids
, nclass
, prinfo
.pr_lwp
.pr_clname
,
979 fatalerr("%s: Bad idtype %d in ids2pids()\n",
983 (void) closedir(dirp
);
988 * Search the array pointed to by clpids for the classpids
989 * structure corresponding to clname and add pid to its
993 add_pid_tolist(clpids
, nclass
, clname
, pid
)
1001 for (clp
= clpids
; clp
!= &clpids
[nclass
]; clp
++) {
1002 if (strcmp(clp
->clp_clname
, clname
) == 0) {
1003 if (clp
->clp_npids
== clp
->clp_pidlistsz
)
1004 increase_pidlist(clp
);
1006 (clp
->clp_pidlist
)[clp
->clp_npids
] = pid
;
1015 increase_pidlist(classpids_t
*clp
)
1017 if ((clp
->clp_pidlist
= reallocarray(clp
->clp_pidlist
,
1018 clp
->clp_pidlistsz
+ NPIDS
, sizeof (pid_t
))) == NULL
)
1020 * The pidlist is filled up and we cannot increase the size.
1022 fatalerr("%s: Can't allocate memory for pidlist.\n", cmdpath
);
1024 clp
->clp_pidlistsz
+= NPIDS
;
1029 * Compare id strings for equality. If idargv contains ids
1030 * (idargc > 0) compare idstr to each id in idargv, otherwise
1031 * just compare to curidstr.
1034 idmatch(idstr
, curidstr
, idargc
, idargv
)
1043 if (strcmp(curidstr
, idstr
) == 0)
1046 for (i
= 0; i
< idargc
; i
++) {
1047 if (strcmp(idargv
[i
], idstr
) == 0)
1055 * This is a copy of the getopt() function found in libc:getopt.c. A separate
1056 * copy is required to fix the bug id #1114636. To fix the problem we need to
1057 * reset the _sp to 1. Since _sp in libc:getopt() is not exposed, a copy of
1058 * the getopt() is kept so that prio_sp can be reset to 1.
1062 prio_getopt(argc
, argv
, opts
)
1065 char *const *argv
, *opts
;
1074 if (prio_optind
>= argc
||
1075 argv
[prio_optind
][0] != '-' || argv
[prio_optind
][1] == '\0')
1077 else if (strcmp(argv
[prio_optind
], "--") == 0) {
1081 prio_optopt
= c
= (unsigned char)argv
[prio_optind
][prio_sp
];
1082 if (c
== ':' || (cp
= strchr(opts
, c
)) == NULL
) {
1083 if (argv
[prio_optind
][++prio_sp
] == '\0') {
1090 if (argv
[prio_optind
][prio_sp
+1] != '\0')
1091 prio_optarg
= &argv
[prio_optind
++][prio_sp
+1];
1092 else if (++prio_optind
>= argc
) {
1096 prio_optarg
= argv
[prio_optind
++];
1099 if (argv
[prio_optind
][++prio_sp
] == '\0') {