xref: /titanic_41/usr/src/lib/libc/port/gen/priocntl.c (revision c2580b931007758eab8cb5ae8726ebe1588e259b)
1 /*
2  * CDDL HEADER START
3  *
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
7  * with the License.
8  *
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.
13  *
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]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*	Copyright (c) 1988 AT&T	*/
30 /*	  All Rights Reserved  	*/
31 
32 
33 #include	"synonyms.h"
34 #include	<sys/types.h>
35 #include	<sys/procset.h>
36 #include	<sys/priocntl.h>
37 #include	<stdarg.h>
38 #include	<errno.h>
39 
40 /*
41  * The declaration of __priocntlset() and __priocntl() was in prior releases
42  * in <sys/priocntl.h>. They are used to define PC_VERSION at compile time,
43  * based on the contents of the header file. This behavior is now changed.
44  * Old binaries call __priocntl() and __priocntlset() instead priocntl() and
45  * priocntlset(). New binaries call priocntl() and priocntlset().
46  */
47 
48 /*
49  * defined in priocntlset.s
50  */
51 extern long __priocntlset(int, procset_t *, int, caddr_t, ...);
52 
53 /*
54  * prototype declaration
55  */
56 long __priocntl(int, idtype_t, id_t, int, caddr_t);
57 
58 
59 static int pc_vaargs2parms(va_list valist, pc_vaparms_t *vp);
60 
61 long
62 __priocntl(int pc_version, idtype_t idtype, id_t id, int cmd, caddr_t arg)
63 {
64 	procset_t	procset;
65 
66 	setprocset(&procset, POP_AND, idtype, id, P_ALL, 0);
67 
68 	return (__priocntlset(pc_version, &procset, cmd, arg, 0));
69 }
70 
71 
72 /*VARARGS3*/
73 long
74 priocntl(idtype_t idtype, id_t id, int cmd, ...)
75 {
76 	procset_t	procset;
77 	va_list		valist;
78 	pc_vaparms_t	varparms;
79 	caddr_t		arg;
80 	int		error;
81 
82 	setprocset(&procset, POP_AND, idtype, id, P_ALL, 0);
83 
84 	va_start(valist, cmd);
85 	arg = va_arg(valist, caddr_t);
86 
87 	if (cmd != PC_GETXPARMS && cmd != PC_SETXPARMS) {
88 		va_end(valist);
89 		return (__priocntlset(PC_VERSION, &procset, cmd, arg, 0));
90 	}
91 
92 	error = pc_vaargs2parms(valist, &varparms);
93 	va_end(valist);
94 
95 	if (error) {
96 		errno = error;
97 		return (-1);
98 	}
99 
100 	return (__priocntlset(PC_VERSION, &procset, cmd, arg, &varparms));
101 }
102 
103 
104 /*VARARGS2*/
105 long
106 priocntlset(procset_t *procsetp, int cmd, ...)
107 {
108 	va_list		valist;
109 	pc_vaparms_t	varparms;
110 	caddr_t		arg;
111 	int		error;
112 
113 	va_start(valist, cmd);
114 	arg = va_arg(valist, caddr_t);
115 
116 	if (cmd != PC_GETXPARMS && cmd != PC_SETXPARMS) {
117 		va_end(valist);
118 		return (__priocntlset(PC_VERSION, procsetp, cmd, arg, 0));
119 	}
120 
121 	error = pc_vaargs2parms(valist, &varparms);
122 	va_end(valist);
123 
124 	if (error) {
125 		errno = error;
126 		return (-1);
127 	}
128 
129 	return (__priocntlset(PC_VERSION, procsetp, cmd, arg, &varparms));
130 }
131 
132 
133 static int
134 pc_vaargs2parms(va_list valist, pc_vaparms_t *vp)
135 {
136 	pc_vaparm_t	*vpp = &vp->pc_parms[0];
137 	int		key;
138 
139 	for (vp->pc_vaparmscnt = 0;
140 	    (key = va_arg(valist, int)) != PC_KY_NULL; vpp++) {
141 		if (++vp->pc_vaparmscnt > PC_VAPARMCNT)
142 			return (EINVAL);
143 
144 		vpp->pc_key = key;
145 		vpp->pc_parm = va_arg(valist, uintptr_t);
146 	}
147 
148 	return (0);
149 }
150