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 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #define _LARGEFILE64_SOURCE 29 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <errno.h> 33 #include <strings.h> 34 #include "libproc.h" 35 #include <sys/rctl_impl.h> 36 37 /* 38 * getrctl() system call -- executed by subject process 39 */ 40 int 41 pr_getrctl(struct ps_prochandle *Pr, const char *rname, 42 rctlblk_t *old_blk, rctlblk_t *new_blk, int rflag) 43 { 44 sysret_t rval; 45 argdes_t argd[6]; 46 argdes_t *adp; 47 int error; 48 49 if (Pr == NULL) /* no subject process */ 50 return (getrctl(rname, old_blk, new_blk, rflag)); 51 52 adp = &argd[0]; 53 adp->arg_value = 0; /* switch for getrctl in rctlsys */ 54 adp->arg_object = NULL; 55 adp->arg_type = AT_BYVAL; 56 adp->arg_inout = AI_INPUT; 57 adp->arg_size = 0; 58 59 adp++; 60 adp->arg_value = 0; 61 adp->arg_object = (void *)rname; 62 adp->arg_type = AT_BYREF; 63 adp->arg_inout = AI_INPUT; 64 adp->arg_size = strlen(rname) + 1; 65 66 adp++; 67 if (old_blk == NULL) { 68 adp->arg_value = 0; 69 adp->arg_object = NULL; 70 adp->arg_type = AT_BYVAL; 71 adp->arg_inout = AI_INPUT; 72 adp->arg_size = 0; 73 } else { 74 adp->arg_value = 0; 75 adp->arg_object = old_blk; 76 adp->arg_type = AT_BYREF; 77 adp->arg_inout = AI_INPUT; 78 adp->arg_size = rctlblk_size(); 79 } 80 81 adp++; 82 if (new_blk == NULL) { 83 adp->arg_value = 0; 84 adp->arg_object = NULL; 85 adp->arg_type = AT_BYVAL; 86 adp->arg_inout = AI_OUTPUT; 87 adp->arg_size = 0; 88 } else { 89 adp->arg_value = 0; 90 adp->arg_object = new_blk; 91 adp->arg_type = AT_BYREF; 92 adp->arg_inout = AI_INOUT; 93 adp->arg_size = rctlblk_size(); 94 } 95 96 adp++; 97 adp->arg_value = 0; /* obufsz isn't used by getrctl() */ 98 adp->arg_object = NULL; 99 adp->arg_type = AT_BYVAL; 100 adp->arg_inout = AI_INPUT; 101 adp->arg_size = 0; 102 103 adp++; 104 adp->arg_value = rflag; 105 adp->arg_object = NULL; 106 adp->arg_type = AT_BYVAL; 107 adp->arg_inout = AI_INPUT; 108 adp->arg_size = 0; 109 110 error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]); 111 112 if (error) { 113 errno = (error > 0) ? error : ENOSYS; 114 return (-1); 115 } 116 return (rval.sys_rval1); 117 } 118 119 /* 120 * setrctl() system call -- executed by subject process 121 */ 122 int 123 pr_setrctl(struct ps_prochandle *Pr, const char *rname, 124 rctlblk_t *old_blk, rctlblk_t *new_blk, int rflag) 125 { 126 sysret_t rval; 127 argdes_t argd[6]; 128 argdes_t *adp; 129 int error; 130 131 if (Pr == NULL) /* no subject process */ 132 return (setrctl(rname, old_blk, new_blk, rflag)); 133 134 adp = &argd[0]; 135 adp->arg_value = 1; /* switch for setrctl in rctlsys */ 136 adp->arg_object = NULL; 137 adp->arg_type = AT_BYVAL; 138 adp->arg_inout = AI_INPUT; 139 adp->arg_size = 0; 140 141 adp++; 142 adp->arg_value = 0; 143 adp->arg_object = (void *)rname; 144 adp->arg_type = AT_BYREF; 145 adp->arg_inout = AI_INPUT; 146 adp->arg_size = strlen(rname) + 1; 147 148 adp++; 149 if (old_blk == NULL) { 150 adp->arg_value = 0; 151 adp->arg_object = NULL; 152 adp->arg_type = AT_BYVAL; 153 adp->arg_inout = AI_INPUT; 154 adp->arg_size = 0; 155 } else { 156 adp->arg_value = 0; 157 adp->arg_object = old_blk; 158 adp->arg_type = AT_BYREF; 159 adp->arg_inout = AI_INPUT; 160 adp->arg_size = rctlblk_size(); 161 } 162 163 adp++; 164 if (new_blk == NULL) { 165 adp->arg_value = 0; 166 adp->arg_object = NULL; 167 adp->arg_type = AT_BYVAL; 168 adp->arg_inout = AI_INPUT; 169 adp->arg_size = 0; 170 } else { 171 adp->arg_value = 0; 172 adp->arg_object = new_blk; 173 adp->arg_type = AT_BYREF; 174 adp->arg_inout = AI_INPUT; 175 adp->arg_size = rctlblk_size(); 176 } 177 178 adp++; 179 adp->arg_value = 0; /* obufsz isn't used by setrctl() */ 180 adp->arg_object = NULL; 181 adp->arg_type = AT_BYVAL; 182 adp->arg_inout = AI_INPUT; 183 adp->arg_size = 0; 184 185 adp++; 186 adp->arg_value = rflag; 187 adp->arg_object = NULL; 188 adp->arg_type = AT_BYVAL; 189 adp->arg_inout = AI_INPUT; 190 adp->arg_size = 0; 191 192 error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]); 193 194 if (error) { 195 errno = (error > 0) ? error : ENOSYS; 196 return (-1); 197 } 198 return (rval.sys_rval1); 199 } 200 201 /* 202 * setprojrctl() system call -- executed by subject process 203 */ 204 int 205 pr_setprojrctl(struct ps_prochandle *Pr, const char *rname, 206 rctlblk_t *new_blk, size_t size, int rflag) 207 { 208 sysret_t rval; 209 argdes_t argd[6]; 210 argdes_t *adp; 211 int error; 212 213 if (Pr == NULL) /* no subject process */ 214 return (setprojrctl(rname, new_blk, size, rflag)); 215 216 adp = &argd[0]; 217 adp->arg_value = 4; /* switch for setprojrctls in rctlsys */ 218 adp->arg_object = NULL; 219 adp->arg_type = AT_BYVAL; 220 adp->arg_inout = AI_INPUT; 221 adp->arg_size = 0; 222 223 adp++; 224 adp->arg_value = 0; 225 adp->arg_object = (void *)rname; 226 adp->arg_type = AT_BYREF; 227 adp->arg_inout = AI_INPUT; 228 adp->arg_size = strlen(rname) + 1; 229 230 adp++; 231 adp->arg_value = 0; /* old_blk is not used by setprojrctls() */ 232 adp->arg_object = NULL; 233 adp->arg_type = AT_BYVAL; 234 adp->arg_inout = AI_INPUT; 235 adp->arg_size = 0; 236 237 238 adp++; 239 if (new_blk == NULL) { 240 adp->arg_value = 0; 241 adp->arg_object = NULL; 242 adp->arg_type = AT_BYVAL; 243 adp->arg_inout = AI_INPUT; 244 adp->arg_size = 0; 245 } else { 246 adp->arg_value = 0; 247 adp->arg_object = new_blk; 248 adp->arg_type = AT_BYREF; 249 adp->arg_inout = AI_INPUT; 250 adp->arg_size = rctlblk_size() * size; 251 } 252 253 adp++; 254 adp->arg_value = size; /* obufsz is used by setrctls() */ 255 adp->arg_object = NULL; 256 adp->arg_type = AT_BYVAL; 257 adp->arg_inout = AI_INPUT; 258 adp->arg_size = 0; 259 260 adp++; 261 adp->arg_value = rflag; 262 adp->arg_object = NULL; 263 adp->arg_type = AT_BYVAL; 264 adp->arg_inout = AI_INPUT; 265 adp->arg_size = 0; 266 267 error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]); 268 269 if (error) { 270 errno = (error > 0) ? error : ENOSYS; 271 return (-1); 272 } 273 return (rval.sys_rval1); 274 } 275