Home | History | Annotate | Download | only in common
      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