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 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 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 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