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 (c) 1997-2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #define	_LARGEFILE64_SOURCE
28 
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <sys/resource.h>
33 #include "libproc.h"
34 
35 /*
36  * getrlimit() system call -- executed by subject process.
37  */
38 int
pr_getrlimit(struct ps_prochandle * Pr,int resource,struct rlimit * rlp)39 pr_getrlimit(struct ps_prochandle *Pr,
40 	int resource, struct rlimit *rlp)
41 {
42 	sysret_t rval;			/* return value from getrlimit() */
43 	argdes_t argd[2];		/* arg descriptors for getrlimit() */
44 	argdes_t *adp;
45 	int sysnum;
46 	int error;
47 
48 	if (Pr == NULL)		/* no subject process */
49 		return (getrlimit(resource, rlp));
50 
51 	adp = &argd[0];		/* resource argument */
52 	adp->arg_value = resource;
53 	adp->arg_object = NULL;
54 	adp->arg_type = AT_BYVAL;
55 	adp->arg_inout = AI_INPUT;
56 	adp->arg_size = 0;
57 
58 	adp++;			/* rlp argument */
59 	adp->arg_value = 0;
60 	adp->arg_object = rlp;
61 	adp->arg_type = AT_BYREF;
62 	adp->arg_inout = AI_OUTPUT;
63 	adp->arg_size = sizeof (*rlp);
64 
65 #ifdef _LP64
66 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
67 		sysnum = SYS_getrlimit64;
68 	else
69 		sysnum = SYS_getrlimit;
70 #else	/* _LP64 */
71 	sysnum = SYS_getrlimit;
72 #endif	/* _LP64 */
73 
74 	error = Psyscall(Pr, &rval, sysnum, 2, &argd[0]);
75 
76 	if (error) {
77 		errno = (error > 0)? error : ENOSYS;
78 		return (-1);
79 	}
80 	return (rval.sys_rval1);
81 }
82 
83 /*
84  * setrlimit() system call -- executed by subject process.
85  */
86 int
pr_setrlimit(struct ps_prochandle * Pr,int resource,const struct rlimit * rlp)87 pr_setrlimit(struct ps_prochandle *Pr,
88 	int resource, const struct rlimit *rlp)
89 {
90 	sysret_t rval;			/* return value from setrlimit() */
91 	argdes_t argd[2];		/* arg descriptors for setrlimit() */
92 	argdes_t *adp;
93 	int sysnum;
94 	int error;
95 
96 	if (Pr == NULL)		/* no subject process */
97 		return (setrlimit(resource, rlp));
98 
99 	adp = &argd[0];		/* resource argument */
100 	adp->arg_value = resource;
101 	adp->arg_object = NULL;
102 	adp->arg_type = AT_BYVAL;
103 	adp->arg_inout = AI_INPUT;
104 	adp->arg_size = 0;
105 
106 	adp++;			/* rlp argument */
107 	adp->arg_value = 0;
108 	adp->arg_object = (void *)rlp;
109 	adp->arg_type = AT_BYREF;
110 	adp->arg_inout = AI_INPUT;
111 	adp->arg_size = sizeof (*rlp);
112 
113 #ifdef _LP64
114 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
115 		sysnum = SYS_setrlimit64;
116 	else
117 		sysnum = SYS_setrlimit;
118 #else	/* _LP64 */
119 	sysnum = SYS_setrlimit;
120 #endif	/* _LP64 */
121 
122 	error = Psyscall(Pr, &rval, sysnum, 2, &argd[0]);
123 
124 	if (error) {
125 		errno = (error > 0)? error : ENOSYS;
126 		return (-1);
127 	}
128 	return (rval.sys_rval1);
129 }
130 
131 /*
132  * getrlimit64() system call -- executed by subject process.
133  */
134 int
pr_getrlimit64(struct ps_prochandle * Pr,int resource,struct rlimit64 * rlp)135 pr_getrlimit64(struct ps_prochandle *Pr,
136 	int resource, struct rlimit64 *rlp)
137 {
138 	sysret_t rval;			/* return value from getrlimit() */
139 	argdes_t argd[2];		/* arg descriptors for getrlimit() */
140 	argdes_t *adp;
141 	int sysnum;
142 	int error;
143 
144 	if (Pr == NULL)		/* no subject process */
145 		return (getrlimit64(resource, rlp));
146 
147 	adp = &argd[0];		/* resource argument */
148 	adp->arg_value = resource;
149 	adp->arg_object = NULL;
150 	adp->arg_type = AT_BYVAL;
151 	adp->arg_inout = AI_INPUT;
152 	adp->arg_size = 0;
153 
154 	adp++;			/* rlp argument */
155 	adp->arg_value = 0;
156 	adp->arg_object = rlp;
157 	adp->arg_type = AT_BYREF;
158 	adp->arg_inout = AI_OUTPUT;
159 	adp->arg_size = sizeof (*rlp);
160 
161 #ifdef _LP64
162 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
163 		sysnum = SYS_getrlimit64;
164 	else
165 		sysnum = SYS_getrlimit;
166 #else	/* _LP64 */
167 	sysnum = SYS_getrlimit64;
168 #endif	/* _LP64 */
169 
170 	error = Psyscall(Pr, &rval, sysnum, 2, &argd[0]);
171 
172 	if (error) {
173 		errno = (error > 0)? error : ENOSYS;
174 		return (-1);
175 	}
176 	return (rval.sys_rval1);
177 }
178 
179 /*
180  * setrlimit64() system call -- executed by subject process.
181  */
182 int
pr_setrlimit64(struct ps_prochandle * Pr,int resource,const struct rlimit64 * rlp)183 pr_setrlimit64(struct ps_prochandle *Pr,
184 	int resource, const struct rlimit64 *rlp)
185 {
186 	sysret_t rval;			/* return value from setrlimit() */
187 	argdes_t argd[2];		/* arg descriptors for setrlimit() */
188 	argdes_t *adp;
189 	int sysnum;
190 	int error;
191 
192 	if (Pr == NULL)		/* no subject process */
193 		return (setrlimit64(resource, rlp));
194 
195 	adp = &argd[0];		/* resource argument */
196 	adp->arg_value = resource;
197 	adp->arg_object = NULL;
198 	adp->arg_type = AT_BYVAL;
199 	adp->arg_inout = AI_INPUT;
200 	adp->arg_size = 0;
201 
202 	adp++;			/* rlp argument */
203 	adp->arg_value = 0;
204 	adp->arg_object = (void *)rlp;
205 	adp->arg_type = AT_BYREF;
206 	adp->arg_inout = AI_INPUT;
207 	adp->arg_size = sizeof (*rlp);
208 
209 #ifdef _LP64
210 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
211 		sysnum = SYS_setrlimit64;
212 	else
213 		sysnum = SYS_setrlimit;
214 #else	/* _LP64 */
215 	sysnum = SYS_setrlimit64;
216 #endif	/* _LP64 */
217 
218 	error = Psyscall(Pr, &rval, sysnum, 2, &argd[0]);
219 
220 	if (error) {
221 		errno = (error > 0)? error : ENOSYS;
222 		return (-1);
223 	}
224 	return (rval.sys_rval1);
225 }
226