]>
Commit | Line | Data |
---|---|---|
9554d330 WL |
1 | /* |
2 | * process related system call shims and definitions | |
3 | * | |
4 | * Copyright (c) 2013-2014 Stacey D. Son | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
20 | #ifndef BSD_PROC_H_ | |
21 | #define BSD_PROC_H_ | |
22 | ||
9554d330 | 23 | #include <sys/resource.h> |
9554d330 | 24 | |
0caa3768 SS |
25 | #include "qemu-bsd.h" |
26 | #include "gdbstub/syscalls.h" | |
27 | #include "qemu/plugin.h" | |
28 | ||
82fe5f3a | 29 | extern int _getlogin(char*, int); |
b623031c KE |
30 | int bsd_get_ncpu(void); |
31 | ||
9554d330 WL |
32 | /* exit(2) */ |
33 | static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1) | |
34 | { | |
9554d330 WL |
35 | gdb_exit(arg1); |
36 | qemu_plugin_user_exit(); | |
37 | _exit(arg1); | |
38 | ||
39 | return 0; | |
40 | } | |
41 | ||
a478416d SS |
42 | /* getgroups(2) */ |
43 | static inline abi_long do_bsd_getgroups(abi_long gidsetsize, abi_long arg2) | |
44 | { | |
45 | abi_long ret; | |
46 | uint32_t *target_grouplist; | |
47 | g_autofree gid_t *grouplist; | |
48 | int i; | |
49 | ||
50 | grouplist = g_try_new(gid_t, gidsetsize); | |
51 | ret = get_errno(getgroups(gidsetsize, grouplist)); | |
52 | if (gidsetsize != 0) { | |
53 | if (!is_error(ret)) { | |
54 | target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); | |
55 | if (!target_grouplist) { | |
56 | return -TARGET_EFAULT; | |
57 | } | |
58 | for (i = 0; i < ret; i++) { | |
59 | target_grouplist[i] = tswap32(grouplist[i]); | |
60 | } | |
61 | unlock_user(target_grouplist, arg2, gidsetsize * 2); | |
62 | } | |
63 | } | |
64 | return ret; | |
65 | } | |
66 | ||
67 | /* setgroups(2) */ | |
68 | static inline abi_long do_bsd_setgroups(abi_long gidsetsize, abi_long arg2) | |
69 | { | |
70 | uint32_t *target_grouplist; | |
71 | g_autofree gid_t *grouplist; | |
72 | int i; | |
73 | ||
74 | grouplist = g_try_new(gid_t, gidsetsize); | |
75 | target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1); | |
76 | if (!target_grouplist) { | |
77 | return -TARGET_EFAULT; | |
78 | } | |
79 | for (i = 0; i < gidsetsize; i++) { | |
80 | grouplist[i] = tswap32(target_grouplist[i]); | |
81 | } | |
82 | unlock_user(target_grouplist, arg2, 0); | |
83 | return get_errno(setgroups(gidsetsize, grouplist)); | |
84 | } | |
85 | ||
82fe5f3a SS |
86 | /* umask(2) */ |
87 | static inline abi_long do_bsd_umask(abi_long arg1) | |
88 | { | |
89 | return get_errno(umask(arg1)); | |
90 | } | |
91 | ||
92 | /* setlogin(2) */ | |
93 | static inline abi_long do_bsd_setlogin(abi_long arg1) | |
94 | { | |
95 | abi_long ret; | |
96 | void *p; | |
97 | ||
98 | p = lock_user_string(arg1); | |
99 | if (p == NULL) { | |
100 | return -TARGET_EFAULT; | |
101 | } | |
102 | ret = get_errno(setlogin(p)); | |
103 | unlock_user(p, arg1, 0); | |
104 | ||
105 | return ret; | |
106 | } | |
107 | ||
108 | /* getlogin(2) */ | |
109 | static inline abi_long do_bsd_getlogin(abi_long arg1, abi_long arg2) | |
110 | { | |
111 | abi_long ret; | |
112 | void *p; | |
113 | ||
114 | p = lock_user(VERIFY_WRITE, arg1, arg2, 0); | |
115 | if (p == NULL) { | |
116 | return -TARGET_EFAULT; | |
117 | } | |
118 | ret = get_errno(_getlogin(p, arg2)); | |
119 | unlock_user(p, arg1, arg2); | |
120 | ||
121 | return ret; | |
122 | } | |
123 | ||
59e801ef SS |
124 | /* getrusage(2) */ |
125 | static inline abi_long do_bsd_getrusage(abi_long who, abi_ulong target_addr) | |
126 | { | |
127 | abi_long ret; | |
128 | struct rusage rusage; | |
129 | ||
130 | ret = get_errno(getrusage(who, &rusage)); | |
131 | if (!is_error(ret)) { | |
132 | host_to_target_rusage(target_addr, &rusage); | |
133 | } | |
134 | return ret; | |
135 | } | |
136 | ||
faba8e12 SS |
137 | /* getrlimit(2) */ |
138 | static inline abi_long do_bsd_getrlimit(abi_long arg1, abi_ulong arg2) | |
139 | { | |
140 | abi_long ret; | |
141 | int resource = target_to_host_resource(arg1); | |
142 | struct target_rlimit *target_rlim; | |
143 | struct rlimit rlim; | |
144 | ||
145 | switch (resource) { | |
146 | case RLIMIT_STACK: | |
147 | rlim.rlim_cur = target_dflssiz; | |
148 | rlim.rlim_max = target_maxssiz; | |
149 | ret = 0; | |
150 | break; | |
151 | ||
152 | case RLIMIT_DATA: | |
153 | rlim.rlim_cur = target_dfldsiz; | |
154 | rlim.rlim_max = target_maxdsiz; | |
155 | ret = 0; | |
156 | break; | |
157 | ||
158 | default: | |
159 | ret = get_errno(getrlimit(resource, &rlim)); | |
160 | break; | |
161 | } | |
162 | if (!is_error(ret)) { | |
163 | if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) { | |
164 | return -TARGET_EFAULT; | |
165 | } | |
166 | target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur); | |
167 | target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max); | |
168 | unlock_user_struct(target_rlim, arg2, 1); | |
169 | } | |
170 | return ret; | |
171 | } | |
172 | ||
173 | /* setrlimit(2) */ | |
174 | static inline abi_long do_bsd_setrlimit(abi_long arg1, abi_ulong arg2) | |
175 | { | |
176 | abi_long ret; | |
177 | int resource = target_to_host_resource(arg1); | |
178 | struct target_rlimit *target_rlim; | |
179 | struct rlimit rlim; | |
180 | ||
181 | if (RLIMIT_STACK == resource) { | |
182 | /* XXX We should, maybe, allow the stack size to shrink */ | |
183 | ret = -TARGET_EPERM; | |
184 | } else { | |
185 | if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) { | |
186 | return -TARGET_EFAULT; | |
187 | } | |
188 | rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur); | |
189 | rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max); | |
190 | unlock_user_struct(target_rlim, arg2, 0); | |
191 | ret = get_errno(setrlimit(resource, &rlim)); | |
192 | } | |
193 | return ret; | |
194 | } | |
195 | ||
e4446e0a SS |
196 | /* getpid(2) */ |
197 | static inline abi_long do_bsd_getpid(void) | |
198 | { | |
199 | return get_errno(getpid()); | |
200 | } | |
201 | ||
202 | /* getppid(2) */ | |
203 | static inline abi_long do_bsd_getppid(void) | |
204 | { | |
205 | return get_errno(getppid()); | |
206 | } | |
207 | ||
208 | /* getuid(2) */ | |
209 | static inline abi_long do_bsd_getuid(void) | |
210 | { | |
211 | return get_errno(getuid()); | |
212 | } | |
213 | ||
214 | /* geteuid(2) */ | |
215 | static inline abi_long do_bsd_geteuid(void) | |
216 | { | |
217 | return get_errno(geteuid()); | |
218 | } | |
219 | ||
220 | /* getgid(2) */ | |
221 | static inline abi_long do_bsd_getgid(void) | |
222 | { | |
223 | return get_errno(getgid()); | |
224 | } | |
225 | ||
226 | /* getegid(2) */ | |
227 | static inline abi_long do_bsd_getegid(void) | |
228 | { | |
229 | return get_errno(getegid()); | |
230 | } | |
231 | ||
232 | /* setuid(2) */ | |
233 | static inline abi_long do_bsd_setuid(abi_long arg1) | |
234 | { | |
235 | return get_errno(setuid(arg1)); | |
236 | } | |
237 | ||
238 | /* seteuid(2) */ | |
239 | static inline abi_long do_bsd_seteuid(abi_long arg1) | |
240 | { | |
241 | return get_errno(seteuid(arg1)); | |
242 | } | |
243 | ||
244 | /* setgid(2) */ | |
245 | static inline abi_long do_bsd_setgid(abi_long arg1) | |
246 | { | |
247 | return get_errno(setgid(arg1)); | |
248 | } | |
249 | ||
250 | /* setegid(2) */ | |
251 | static inline abi_long do_bsd_setegid(abi_long arg1) | |
252 | { | |
253 | return get_errno(setegid(arg1)); | |
254 | } | |
255 | ||
256 | /* getpgid(2) */ | |
257 | static inline abi_long do_bsd_getpgid(pid_t pid) | |
258 | { | |
259 | return get_errno(getpgid(pid)); | |
260 | } | |
261 | ||
262 | /* setpgid(2) */ | |
263 | static inline abi_long do_bsd_setpgid(int pid, int pgrp) | |
264 | { | |
265 | return get_errno(setpgid(pid, pgrp)); | |
266 | } | |
267 | ||
268 | /* getpgrp(2) */ | |
269 | static inline abi_long do_bsd_getpgrp(void) | |
270 | { | |
271 | return get_errno(getpgrp()); | |
272 | } | |
273 | ||
274 | /* setreuid(2) */ | |
275 | static inline abi_long do_bsd_setreuid(abi_long arg1, abi_long arg2) | |
276 | { | |
277 | return get_errno(setreuid(arg1, arg2)); | |
278 | } | |
279 | ||
280 | /* setregid(2) */ | |
281 | static inline abi_long do_bsd_setregid(abi_long arg1, abi_long arg2) | |
282 | { | |
283 | return get_errno(setregid(arg1, arg2)); | |
284 | } | |
285 | ||
932683c3 SS |
286 | /* setresgid(2) */ |
287 | static inline abi_long do_bsd_setresgid(gid_t rgid, gid_t egid, gid_t sgid) | |
288 | { | |
289 | return get_errno(setresgid(rgid, egid, sgid)); | |
290 | } | |
291 | ||
292 | /* setresuid(2) */ | |
293 | static inline abi_long do_bsd_setresuid(uid_t ruid, uid_t euid, uid_t suid) | |
294 | { | |
295 | return get_errno(setresuid(ruid, euid, suid)); | |
296 | } | |
297 | ||
298 | /* getresuid(2) */ | |
299 | static inline abi_long do_bsd_getresuid(abi_ulong arg1, abi_ulong arg2, | |
300 | abi_ulong arg3) | |
301 | { | |
302 | abi_long ret; | |
303 | uid_t ruid, euid, suid; | |
304 | ||
305 | ret = get_errno(getresuid(&ruid, &euid, &suid)); | |
306 | if (is_error(ret)) { | |
307 | return ret; | |
308 | } | |
309 | if (put_user_s32(ruid, arg1)) { | |
310 | return -TARGET_EFAULT; | |
311 | } | |
312 | if (put_user_s32(euid, arg2)) { | |
313 | return -TARGET_EFAULT; | |
314 | } | |
315 | if (put_user_s32(suid, arg3)) { | |
316 | return -TARGET_EFAULT; | |
317 | } | |
318 | return ret; | |
319 | } | |
320 | ||
321 | /* getresgid(2) */ | |
322 | static inline abi_long do_bsd_getresgid(abi_ulong arg1, abi_ulong arg2, | |
323 | abi_ulong arg3) | |
324 | { | |
325 | abi_long ret; | |
326 | uid_t ruid, euid, suid; | |
327 | ||
328 | ret = get_errno(getresgid(&ruid, &euid, &suid)); | |
329 | if (is_error(ret)) { | |
330 | return ret; | |
331 | } | |
332 | if (put_user_s32(ruid, arg1)) { | |
333 | return -TARGET_EFAULT; | |
334 | } | |
335 | if (put_user_s32(euid, arg2)) { | |
336 | return -TARGET_EFAULT; | |
337 | } | |
338 | if (put_user_s32(suid, arg3)) { | |
339 | return -TARGET_EFAULT; | |
340 | } | |
341 | return ret; | |
342 | } | |
343 | ||
344 | /* getsid(2) */ | |
345 | static inline abi_long do_bsd_getsid(abi_long arg1) | |
346 | { | |
347 | return get_errno(getsid(arg1)); | |
348 | } | |
349 | ||
350 | /* setsid(2) */ | |
351 | static inline abi_long do_bsd_setsid(void) | |
352 | { | |
353 | return get_errno(setsid()); | |
354 | } | |
355 | ||
356 | /* issetugid(2) */ | |
357 | static inline abi_long do_bsd_issetugid(void) | |
358 | { | |
359 | return get_errno(issetugid()); | |
360 | } | |
361 | ||
615ad41c SS |
362 | /* profil(2) */ |
363 | static inline abi_long do_bsd_profil(abi_long arg1, abi_long arg2, | |
364 | abi_long arg3, abi_long arg4) | |
365 | { | |
366 | return -TARGET_ENOSYS; | |
367 | } | |
368 | ||
369 | /* ktrace(2) */ | |
370 | static inline abi_long do_bsd_ktrace(abi_long arg1, abi_long arg2, | |
371 | abi_long arg3, abi_long arg4) | |
372 | { | |
373 | return -TARGET_ENOSYS; | |
374 | } | |
375 | ||
376 | /* utrace(2) */ | |
377 | static inline abi_long do_bsd_utrace(abi_long arg1, abi_long arg2) | |
378 | { | |
379 | return -TARGET_ENOSYS; | |
380 | } | |
381 | ||
382 | ||
383 | /* ptrace(2) */ | |
384 | static inline abi_long do_bsd_ptrace(abi_long arg1, abi_long arg2, | |
385 | abi_long arg3, abi_long arg4) | |
386 | { | |
387 | return -TARGET_ENOSYS; | |
388 | } | |
389 | ||
ff266372 SS |
390 | /* getpriority(2) */ |
391 | static inline abi_long do_bsd_getpriority(abi_long which, abi_long who) | |
392 | { | |
393 | abi_long ret; | |
394 | /* | |
395 | * Note that negative values are valid for getpriority, so we must | |
396 | * differentiate based on errno settings. | |
397 | */ | |
398 | errno = 0; | |
399 | ret = getpriority(which, who); | |
400 | if (ret == -1 && errno != 0) { | |
401 | return -host_to_target_errno(errno); | |
402 | } | |
403 | ||
404 | return ret; | |
405 | } | |
406 | ||
407 | /* setpriority(2) */ | |
408 | static inline abi_long do_bsd_setpriority(abi_long which, abi_long who, | |
409 | abi_long prio) | |
410 | { | |
411 | return get_errno(setpriority(which, who, prio)); | |
412 | } | |
413 | ||
9554d330 | 414 | #endif /* !BSD_PROC_H_ */ |