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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #define _LARGEFILE64_SOURCE
27
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <strings.h>
32 #include "libproc.h"
33 #include <sys/rctl_impl.h>
34
35 /*
36 * getrctl() system call -- executed by subject process
37 */
38 int
pr_getrctl(struct ps_prochandle * Pr,const char * rname,rctlblk_t * old_blk,rctlblk_t * new_blk,int rflag)39 pr_getrctl(struct ps_prochandle *Pr, const char *rname,
40 rctlblk_t *old_blk, rctlblk_t *new_blk, int rflag)
41 {
42 sysret_t rval;
43 argdes_t argd[6];
44 argdes_t *adp;
45 int error;
46
47 if (Pr == NULL) /* no subject process */
48 return (getrctl(rname, old_blk, new_blk, rflag));
49
50 adp = &argd[0];
51 adp->arg_value = 0; /* switch for getrctl in rctlsys */
52 adp->arg_object = NULL;
53 adp->arg_type = AT_BYVAL;
54 adp->arg_inout = AI_INPUT;
55 adp->arg_size = 0;
56
57 adp++;
58 adp->arg_value = 0;
59 adp->arg_object = (void *)rname;
60 adp->arg_type = AT_BYREF;
61 adp->arg_inout = AI_INPUT;
62 adp->arg_size = strlen(rname) + 1;
63
64 adp++;
65 if (old_blk == NULL) {
66 adp->arg_value = 0;
67 adp->arg_object = NULL;
68 adp->arg_type = AT_BYVAL;
69 adp->arg_inout = AI_INPUT;
70 adp->arg_size = 0;
71 } else {
72 adp->arg_value = 0;
73 adp->arg_object = old_blk;
74 adp->arg_type = AT_BYREF;
75 adp->arg_inout = AI_INPUT;
76 adp->arg_size = rctlblk_size();
77 }
78
79 adp++;
80 if (new_blk == NULL) {
81 adp->arg_value = 0;
82 adp->arg_object = NULL;
83 adp->arg_type = AT_BYVAL;
84 adp->arg_inout = AI_OUTPUT;
85 adp->arg_size = 0;
86 } else {
87 adp->arg_value = 0;
88 adp->arg_object = new_blk;
89 adp->arg_type = AT_BYREF;
90 adp->arg_inout = AI_INOUT;
91 adp->arg_size = rctlblk_size();
92 }
93
94 adp++;
95 adp->arg_value = 0; /* obufsz isn't used by getrctl() */
96 adp->arg_object = NULL;
97 adp->arg_type = AT_BYVAL;
98 adp->arg_inout = AI_INPUT;
99 adp->arg_size = 0;
100
101 adp++;
102 adp->arg_value = rflag;
103 adp->arg_object = NULL;
104 adp->arg_type = AT_BYVAL;
105 adp->arg_inout = AI_INPUT;
106 adp->arg_size = 0;
107
108 error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]);
109
110 if (error) {
111 errno = (error > 0) ? error : ENOSYS;
112 return (-1);
113 }
114 return (rval.sys_rval1);
115 }
116
117 /*
118 * setrctl() system call -- executed by subject process
119 */
120 int
pr_setrctl(struct ps_prochandle * Pr,const char * rname,rctlblk_t * old_blk,rctlblk_t * new_blk,int rflag)121 pr_setrctl(struct ps_prochandle *Pr, const char *rname,
122 rctlblk_t *old_blk, rctlblk_t *new_blk, int rflag)
123 {
124 sysret_t rval;
125 argdes_t argd[6];
126 argdes_t *adp;
127 int error;
128
129 if (Pr == NULL) /* no subject process */
130 return (setrctl(rname, old_blk, new_blk, rflag));
131
132 adp = &argd[0];
133 adp->arg_value = 1; /* switch for setrctl in rctlsys */
134 adp->arg_object = NULL;
135 adp->arg_type = AT_BYVAL;
136 adp->arg_inout = AI_INPUT;
137 adp->arg_size = 0;
138
139 adp++;
140 adp->arg_value = 0;
141 adp->arg_object = (void *)rname;
142 adp->arg_type = AT_BYREF;
143 adp->arg_inout = AI_INPUT;
144 adp->arg_size = strlen(rname) + 1;
145
146 adp++;
147 if (old_blk == NULL) {
148 adp->arg_value = 0;
149 adp->arg_object = NULL;
150 adp->arg_type = AT_BYVAL;
151 adp->arg_inout = AI_INPUT;
152 adp->arg_size = 0;
153 } else {
154 adp->arg_value = 0;
155 adp->arg_object = old_blk;
156 adp->arg_type = AT_BYREF;
157 adp->arg_inout = AI_INPUT;
158 adp->arg_size = rctlblk_size();
159 }
160
161 adp++;
162 if (new_blk == NULL) {
163 adp->arg_value = 0;
164 adp->arg_object = NULL;
165 adp->arg_type = AT_BYVAL;
166 adp->arg_inout = AI_INPUT;
167 adp->arg_size = 0;
168 } else {
169 adp->arg_value = 0;
170 adp->arg_object = new_blk;
171 adp->arg_type = AT_BYREF;
172 adp->arg_inout = AI_INPUT;
173 adp->arg_size = rctlblk_size();
174 }
175
176 adp++;
177 adp->arg_value = 0; /* obufsz isn't used by setrctl() */
178 adp->arg_object = NULL;
179 adp->arg_type = AT_BYVAL;
180 adp->arg_inout = AI_INPUT;
181 adp->arg_size = 0;
182
183 adp++;
184 adp->arg_value = rflag;
185 adp->arg_object = NULL;
186 adp->arg_type = AT_BYVAL;
187 adp->arg_inout = AI_INPUT;
188 adp->arg_size = 0;
189
190 error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]);
191
192 if (error) {
193 errno = (error > 0) ? error : ENOSYS;
194 return (-1);
195 }
196 return (rval.sys_rval1);
197 }
198
199 /*
200 * setprojrctl() system call -- executed by subject process
201 */
202 int
pr_setprojrctl(struct ps_prochandle * Pr,const char * rname,rctlblk_t * new_blk,size_t size,int rflag)203 pr_setprojrctl(struct ps_prochandle *Pr, const char *rname,
204 rctlblk_t *new_blk, size_t size, int rflag)
205 {
206 sysret_t rval;
207 argdes_t argd[6];
208 argdes_t *adp;
209 int error;
210
211 if (Pr == NULL) /* no subject process */
212 return (setprojrctl(rname, new_blk, size, rflag));
213
214 adp = &argd[0];
215 adp->arg_value = 4; /* switch for setprojrctls in rctlsys */
216 adp->arg_object = NULL;
217 adp->arg_type = AT_BYVAL;
218 adp->arg_inout = AI_INPUT;
219 adp->arg_size = 0;
220
221 adp++;
222 adp->arg_value = 0;
223 adp->arg_object = (void *)rname;
224 adp->arg_type = AT_BYREF;
225 adp->arg_inout = AI_INPUT;
226 adp->arg_size = strlen(rname) + 1;
227
228 adp++;
229 adp->arg_value = 0; /* old_blk is not used by setprojrctls() */
230 adp->arg_object = NULL;
231 adp->arg_type = AT_BYVAL;
232 adp->arg_inout = AI_INPUT;
233 adp->arg_size = 0;
234
235
236 adp++;
237 if (new_blk == NULL) {
238 adp->arg_value = 0;
239 adp->arg_object = NULL;
240 adp->arg_type = AT_BYVAL;
241 adp->arg_inout = AI_INPUT;
242 adp->arg_size = 0;
243 } else {
244 adp->arg_value = 0;
245 adp->arg_object = new_blk;
246 adp->arg_type = AT_BYREF;
247 adp->arg_inout = AI_INPUT;
248 adp->arg_size = rctlblk_size() * size;
249 }
250
251 adp++;
252 adp->arg_value = size; /* obufsz is used by setrctls() */
253 adp->arg_object = NULL;
254 adp->arg_type = AT_BYVAL;
255 adp->arg_inout = AI_INPUT;
256 adp->arg_size = 0;
257
258 adp++;
259 adp->arg_value = rflag;
260 adp->arg_object = NULL;
261 adp->arg_type = AT_BYVAL;
262 adp->arg_inout = AI_INPUT;
263 adp->arg_size = 0;
264
265 error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]);
266
267 if (error) {
268 errno = (error > 0) ? error : ENOSYS;
269 return (-1);
270 }
271 return (rval.sys_rval1);
272 }
273