Deleted Added
full compact
linux_misc.c (80180) linux_misc.c (83221)
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/compat/linux/linux_misc.c 80180 2001-07-23 06:22:10Z pirzyk $
28 * $FreeBSD: head/sys/compat/linux/linux_misc.c 83221 2001-09-08 19:07:04Z marcel $
29 */
30
31#include "opt_compat.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/fcntl.h>
36#include <sys/imgact_aout.h>
37#include <sys/kernel.h>
38#include <sys/lock.h>
39#include <sys/mman.h>
40#include <sys/mount.h>
41#include <sys/mutex.h>
42#include <sys/namei.h>
29 */
30
31#include "opt_compat.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/fcntl.h>
36#include <sys/imgact_aout.h>
37#include <sys/kernel.h>
38#include <sys/lock.h>
39#include <sys/mman.h>
40#include <sys/mount.h>
41#include <sys/mutex.h>
42#include <sys/namei.h>
43#include <sys/poll.h>
43#include <sys/proc.h>
44#include <sys/blist.h>
45#include <sys/reboot.h>
46#include <sys/resourcevar.h>
47#include <sys/signalvar.h>
48#include <sys/stat.h>
49#include <sys/sysctl.h>
50#include <sys/sysproto.h>

--- 29 unchanged lines hidden (view full) ---

80
81#ifdef __alpha__
82#define BSD_TO_LINUX_SIGNAL(sig) (sig)
83#else
84#define BSD_TO_LINUX_SIGNAL(sig) \
85 (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig)
86#endif
87
44#include <sys/proc.h>
45#include <sys/blist.h>
46#include <sys/reboot.h>
47#include <sys/resourcevar.h>
48#include <sys/signalvar.h>
49#include <sys/stat.h>
50#include <sys/sysctl.h>
51#include <sys/sysproto.h>

--- 29 unchanged lines hidden (view full) ---

81
82#ifdef __alpha__
83#define BSD_TO_LINUX_SIGNAL(sig) (sig)
84#else
85#define BSD_TO_LINUX_SIGNAL(sig) \
86 (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig)
87#endif
88
88struct linux_rlimit {
89 unsigned long rlim_cur;
90 unsigned long rlim_max;
91};
92
93#ifndef __alpha__
89#ifndef __alpha__
94static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] =
95{ RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK,
96 RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE,
97 RLIMIT_MEMLOCK, -1
90static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = {
91 RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK,
92 RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE,
93 RLIMIT_MEMLOCK, -1
98};
99#endif /*!__alpha__*/
100
94};
95#endif /*!__alpha__*/
96
101struct linux_sysinfo {
102 long uptime; /* Seconds since boot */
103 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
104 unsigned long totalram; /* Total usable main memory size */
105 unsigned long freeram; /* Available memory size */
106 unsigned long sharedram; /* Amount of shared memory */
107 unsigned long bufferram; /* Memory used by buffers */
108 unsigned long totalswap; /* Total swap space size */
109 unsigned long freeswap; /* swap space still available */
110 unsigned short procs; /* Number of current processes */
111 char _f[22]; /* Pads structure to 64 bytes */
97struct l_sysinfo {
98 l_long uptime; /* Seconds since boot */
99 l_ulong loads[3]; /* 1, 5, and 15 minute load averages */
100 l_ulong totalram; /* Total usable main memory size */
101 l_ulong freeram; /* Available memory size */
102 l_ulong sharedram; /* Amount of shared memory */
103 l_ulong bufferram; /* Memory used by buffers */
104 l_ulong totalswap; /* Total swap space size */
105 l_ulong freeswap; /* swap space still available */
106 l_ushort procs; /* Number of current processes */
107 char _f[22]; /* Pads structure to 64 bytes */
112};
108};
113
114#ifndef __alpha__
115int
116linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args)
117{
109#ifndef __alpha__
110int
111linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args)
112{
118 struct linux_sysinfo sysinfo;
119 vm_object_t object;
120 int i;
121 struct timespec ts;
113 struct l_sysinfo sysinfo;
114 vm_object_t object;
115 int i;
116 struct timespec ts;
122
117
123 /* Uptime is copied out of print_uptime() procedure in kern_shutdown.c */
124 getnanouptime(&ts);
125 i = 0;
126 if (ts.tv_sec >= 86400) {
127 ts.tv_sec %= 86400;
128 i = 1;
129 }
130 if (i || ts.tv_sec >= 3600) {
131 ts.tv_sec %= 3600;
132 i = 1;
133 }
134 if (i || ts.tv_sec >= 60) {
135 ts.tv_sec %= 60;
136 i = 1;
137 }
138 sysinfo.uptime=ts.tv_sec;
118 /* Uptime is copied out of print_uptime() in kern_shutdown.c */
119 getnanouptime(&ts);
120 i = 0;
121 if (ts.tv_sec >= 86400) {
122 ts.tv_sec %= 86400;
123 i = 1;
124 }
125 if (i || ts.tv_sec >= 3600) {
126 ts.tv_sec %= 3600;
127 i = 1;
128 }
129 if (i || ts.tv_sec >= 60) {
130 ts.tv_sec %= 60;
131 i = 1;
132 }
133 sysinfo.uptime=ts.tv_sec;
139
134
140 /* Use the information from the mib to get our load averages */
141 for (i = 0; i < 3; i++)
142 sysinfo.loads[i] = averunnable.ldavg[i];
135 /* Use the information from the mib to get our load averages */
136 for (i = 0; i < 3; i++)
137 sysinfo.loads[i] = averunnable.ldavg[i];
143
138
144 sysinfo.totalram = physmem * PAGE_SIZE;
145 sysinfo.freeram = sysinfo.totalram - cnt.v_wire_count * PAGE_SIZE;
139 sysinfo.totalram = physmem * PAGE_SIZE;
140 sysinfo.freeram = sysinfo.totalram - cnt.v_wire_count * PAGE_SIZE;
146
141
147 sysinfo.sharedram = 0;
148 for (object = TAILQ_FIRST(&vm_object_list); object != NULL;
149 object = TAILQ_NEXT(object, object_list))
150 if (object->shadow_count > 1)
151 sysinfo.sharedram += object->resident_page_count;
142 sysinfo.sharedram = 0;
143 for (object = TAILQ_FIRST(&vm_object_list); object != NULL;
144 object = TAILQ_NEXT(object, object_list))
145 if (object->shadow_count > 1)
146 sysinfo.sharedram += object->resident_page_count;
152
147
153 sysinfo.sharedram *= PAGE_SIZE;
148 sysinfo.sharedram *= PAGE_SIZE;
149 sysinfo.bufferram = 0;
154
150
155 sysinfo.bufferram = 0;
151 if (swapblist == NULL) {
152 sysinfo.totalswap= 0;
153 sysinfo.freeswap = 0;
154 } else {
155 sysinfo.totalswap = swapblist->bl_blocks * 1024;
156 sysinfo.freeswap = swapblist->bl_root->u.bmu_avail * PAGE_SIZE;
157 }
156
158
157 if (swapblist == NULL) {
158 sysinfo.totalswap= 0;
159 sysinfo.freeswap = 0;
160 } else {
161 sysinfo.totalswap = swapblist->bl_blocks * 1024;
162 sysinfo.freeswap = swapblist->bl_root->u.bmu_avail * PAGE_SIZE;
163 }
159 sysinfo.procs = 20; /* Hack */
164
160
165 sysinfo.procs = 20; /* Hack */
166
167 return copyout((caddr_t)&sysinfo, (caddr_t)args->info,
168 sizeof(struct linux_sysinfo));
161 return copyout(&sysinfo, (caddr_t)args->info, sizeof(sysinfo));
169}
170#endif /*!__alpha__*/
171
172#ifndef __alpha__
173int
174linux_alarm(struct proc *p, struct linux_alarm_args *args)
175{
162}
163#endif /*!__alpha__*/
164
165#ifndef __alpha__
166int
167linux_alarm(struct proc *p, struct linux_alarm_args *args)
168{
176 struct itimerval it, old_it;
177 struct timeval tv;
178 int s;
169 struct itimerval it, old_it;
170 struct timeval tv;
171 int s;
179
180#ifdef DEBUG
181 if (ldebug(alarm))
182 printf(ARGS(alarm, "%u"), args->secs);
183#endif
172
173#ifdef DEBUG
174 if (ldebug(alarm))
175 printf(ARGS(alarm, "%u"), args->secs);
176#endif
184 if (args->secs > 100000000)
185 return EINVAL;
186 it.it_value.tv_sec = (long)args->secs;
187 it.it_value.tv_usec = 0;
188 it.it_interval.tv_sec = 0;
189 it.it_interval.tv_usec = 0;
190 s = splsoftclock();
191 old_it = p->p_realtimer;
192 getmicrouptime(&tv);
193 if (timevalisset(&old_it.it_value))
194 callout_stop(&p->p_itcallout);
195 if (it.it_value.tv_sec != 0) {
196 callout_reset(&p->p_itcallout, tvtohz(&it.it_value), realitexpire, p);
197 timevaladd(&it.it_value, &tv);
198 }
199 p->p_realtimer = it;
200 splx(s);
201 if (timevalcmp(&old_it.it_value, &tv, >)) {
202 timevalsub(&old_it.it_value, &tv);
203 if (old_it.it_value.tv_usec != 0)
204 old_it.it_value.tv_sec++;
205 p->p_retval[0] = old_it.it_value.tv_sec;
206 }
207 return 0;
177
178 if (args->secs > 100000000)
179 return EINVAL;
180
181 it.it_value.tv_sec = (long)args->secs;
182 it.it_value.tv_usec = 0;
183 it.it_interval.tv_sec = 0;
184 it.it_interval.tv_usec = 0;
185 s = splsoftclock();
186 old_it = p->p_realtimer;
187 getmicrouptime(&tv);
188 if (timevalisset(&old_it.it_value))
189 callout_stop(&p->p_itcallout);
190 if (it.it_value.tv_sec != 0) {
191 callout_reset(&p->p_itcallout, tvtohz(&it.it_value),
192 realitexpire, p);
193 timevaladd(&it.it_value, &tv);
194 }
195 p->p_realtimer = it;
196 splx(s);
197 if (timevalcmp(&old_it.it_value, &tv, >)) {
198 timevalsub(&old_it.it_value, &tv);
199 if (old_it.it_value.tv_usec != 0)
200 old_it.it_value.tv_sec++;
201 p->p_retval[0] = old_it.it_value.tv_sec;
202 }
203 return 0;
208}
209#endif /*!__alpha__*/
210
211int
212linux_brk(struct proc *p, struct linux_brk_args *args)
213{
204}
205#endif /*!__alpha__*/
206
207int
208linux_brk(struct proc *p, struct linux_brk_args *args)
209{
214#if 0
215 struct vmspace *vm = p->p_vmspace;
216 vm_offset_t new, old;
217 int error;
210 struct vmspace *vm = p->p_vmspace;
211 vm_offset_t new, old;
212 struct obreak_args /* {
213 char * nsize;
214 } */ tmp;
218
215
219 if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr)
220 return EINVAL;
221 if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr)
222 > p->p_rlimit[RLIMIT_DATA].rlim_cur)
223 return ENOMEM;
224
225 old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize);
226 new = round_page((vm_offset_t)args->dsend);
227 p->p_retval[0] = old;
228 if ((new-old) > 0) {
229 if (swap_pager_full)
230 return ENOMEM;
231 error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE,
232 VM_PROT_ALL, VM_PROT_ALL, 0);
233 if (error)
234 return error;
235 vm->vm_dsize += btoc((new-old));
236 p->p_retval[0] = (int)(vm->vm_daddr + ctob(vm->vm_dsize));
237 }
238 return 0;
239#else
240 struct vmspace *vm = p->p_vmspace;
241 vm_offset_t new, old;
242 struct obreak_args /* {
243 char * nsize;
244 } */ tmp;
245
246#ifdef DEBUG
247 if (ldebug(brk))
248 printf(ARGS(brk, "%p"), (void *)args->dsend);
249#endif
216#ifdef DEBUG
217 if (ldebug(brk))
218 printf(ARGS(brk, "%p"), (void *)args->dsend);
219#endif
250 old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize);
251 new = (vm_offset_t)args->dsend;
252 tmp.nsize = (char *) new;
253 if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp))
254 p->p_retval[0] = (long)new;
255 else
256 p->p_retval[0] = (long)old;
220 old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize);
221 new = (vm_offset_t)args->dsend;
222 tmp.nsize = (char *) new;
223 if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp))
224 p->p_retval[0] = (long)new;
225 else
226 p->p_retval[0] = (long)old;
257
227
258 return 0;
259#endif
228 return 0;
260}
261
262int
263linux_uselib(struct proc *p, struct linux_uselib_args *args)
264{
229}
230
231int
232linux_uselib(struct proc *p, struct linux_uselib_args *args)
233{
265 struct nameidata ni;
266 struct vnode *vp;
267 struct exec *a_out;
268 struct vattr attr;
269 vm_offset_t vmaddr;
270 unsigned long file_offset;
271 vm_offset_t buffer;
272 unsigned long bss_size;
273 int error;
274 caddr_t sg;
275 int locked;
234 struct nameidata ni;
235 struct vnode *vp;
236 struct exec *a_out;
237 struct vattr attr;
238 vm_offset_t vmaddr;
239 unsigned long file_offset;
240 vm_offset_t buffer;
241 unsigned long bss_size;
242 int error;
243 caddr_t sg;
244 int locked;
276
245
277 sg = stackgap_init();
278 CHECKALTEXIST(p, &sg, args->library);
246 sg = stackgap_init();
247 CHECKALTEXIST(p, &sg, args->library);
279
280#ifdef DEBUG
281 if (ldebug(uselib))
282 printf(ARGS(uselib, "%s"), args->library);
283#endif
284
248
249#ifdef DEBUG
250 if (ldebug(uselib))
251 printf(ARGS(uselib, "%s"), args->library);
252#endif
253
285 a_out = NULL;
286 locked = 0;
287 vp = NULL;
254 a_out = NULL;
255 locked = 0;
256 vp = NULL;
288
257
289 NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, args->library, p);
290 error = namei(&ni);
291 if (error)
292 goto cleanup;
258 NDINIT(&ni, LOOKUP, FOLLOW|LOCKLEAF, UIO_USERSPACE, args->library, p);
259 error = namei(&ni);
260 if (error)
261 goto cleanup;
293
262
294 vp = ni.ni_vp;
295 /*
296 * XXX This looks like a bogus check - a LOCKLEAF namei should not succeed
297 * without returning a vnode.
298 */
299 if (vp == NULL) {
300 error = ENOEXEC; /* ?? */
301 goto cleanup;
302 }
303 NDFREE(&ni, NDF_ONLY_PNBUF);
263 vp = ni.ni_vp;
264 /*
265 * XXX - This looks like a bogus check. A LOCKLEAF namei should not
266 * succeed without returning a vnode.
267 */
268 if (vp == NULL) {
269 error = ENOEXEC; /* ?? */
270 goto cleanup;
271 }
272 NDFREE(&ni, NDF_ONLY_PNBUF);
304
273
305 /*
306 * From here on down, we have a locked vnode that must be unlocked.
307 */
308 locked++;
274 /*
275 * From here on down, we have a locked vnode that must be unlocked.
276 */
277 locked++;
309
278
310 /*
311 * Writable?
312 */
313 if (vp->v_writecount) {
314 error = ETXTBSY;
315 goto cleanup;
316 }
279 /* Writable? */
280 if (vp->v_writecount) {
281 error = ETXTBSY;
282 goto cleanup;
283 }
317
284
318 /*
319 * Executable?
320 */
321 error = VOP_GETATTR(vp, &attr, p->p_ucred, p);
322 if (error)
323 goto cleanup;
285 /* Executable? */
286 error = VOP_GETATTR(vp, &attr, p->p_ucred, p);
287 if (error)
288 goto cleanup;
324
289
325 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
326 ((attr.va_mode & 0111) == 0) ||
327 (attr.va_type != VREG)) {
328 error = ENOEXEC;
329 goto cleanup;
330 }
290 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
291 ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) {
292 error = ENOEXEC;
293 goto cleanup;
294 }
331
295
332 /*
333 * Sensible size?
334 */
335 if (attr.va_size == 0) {
336 error = ENOEXEC;
337 goto cleanup;
338 }
296 /* Sensible size? */
297 if (attr.va_size == 0) {
298 error = ENOEXEC;
299 goto cleanup;
300 }
339
301
340 /*
341 * Can we access it?
342 */
343 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
344 if (error)
345 goto cleanup;
302 /* Can we access it? */
303 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
304 if (error)
305 goto cleanup;
346
306
347 error = VOP_OPEN(vp, FREAD, p->p_ucred, p);
348 if (error)
349 goto cleanup;
307 error = VOP_OPEN(vp, FREAD, p->p_ucred, p);
308 if (error)
309 goto cleanup;
350
310
351 /*
352 * Lock no longer needed
353 */
354 VOP_UNLOCK(vp, 0, p);
355 locked = 0;
311 /*
312 * Lock no longer needed
313 */
314 VOP_UNLOCK(vp, 0, p);
315 locked = 0;
356
316
357 /*
358 * Pull in executable header into kernel_map
359 */
360 error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, PAGE_SIZE,
361 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0);
362 if (error)
363 goto cleanup;
317 /* Pull in executable header into kernel_map */
318 error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, PAGE_SIZE,
319 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0);
320 if (error)
321 goto cleanup;
364
322
365 /*
366 * Is it a Linux binary ?
367 */
368 if (((a_out->a_magic >> 16) & 0xff) != 0x64) {
369 error = ENOEXEC;
370 goto cleanup;
371 }
323 /* Is it a Linux binary ? */
324 if (((a_out->a_magic >> 16) & 0xff) != 0x64) {
325 error = ENOEXEC;
326 goto cleanup;
327 }
372
328
373 /* While we are here, we should REALLY do some more checks */
329 /*
330 * While we are here, we should REALLY do some more checks
331 */
374
332
375 /*
376 * Set file/virtual offset based on a.out variant.
377 */
378 switch ((int)(a_out->a_magic & 0xffff)) {
379 case 0413: /* ZMAGIC */
380 file_offset = 1024;
381 break;
382 case 0314: /* QMAGIC */
383 file_offset = 0;
384 break;
385 default:
386 error = ENOEXEC;
387 goto cleanup;
388 }
333 /* Set file/virtual offset based on a.out variant. */
334 switch ((int)(a_out->a_magic & 0xffff)) {
335 case 0413: /* ZMAGIC */
336 file_offset = 1024;
337 break;
338 case 0314: /* QMAGIC */
339 file_offset = 0;
340 break;
341 default:
342 error = ENOEXEC;
343 goto cleanup;
344 }
389
345
390 bss_size = round_page(a_out->a_bss);
346 bss_size = round_page(a_out->a_bss);
391
347
392 /*
393 * Check various fields in header for validity/bounds.
394 */
395 if (a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK) {
396 error = ENOEXEC;
397 goto cleanup;
398 }
348 /* Check various fields in header for validity/bounds. */
349 if (a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK) {
350 error = ENOEXEC;
351 goto cleanup;
352 }
399
353
400 /* text + data can't exceed file size */
401 if (a_out->a_data + a_out->a_text > attr.va_size) {
402 error = EFAULT;
403 goto cleanup;
404 }
354 /* text + data can't exceed file size */
355 if (a_out->a_data + a_out->a_text > attr.va_size) {
356 error = EFAULT;
357 goto cleanup;
358 }
405
359
406 /* To protect p->p_rlimit in the if condition. */
407 mtx_assert(&Giant, MA_OWNED);
360 /* To protect p->p_rlimit in the if condition. */
361 mtx_assert(&Giant, MA_OWNED);
408
362
409 /*
410 * text/data/bss must not exceed limits
411 * XXX: this is not complete. it should check current usage PLUS
412 * the resources needed by this library.
413 */
414 if (a_out->a_text > MAXTSIZ ||
415 a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur) {
416 error = ENOMEM;
417 goto cleanup;
418 }
363 /*
364 * text/data/bss must not exceed limits
365 * XXX - this is not complete. it should check current usage PLUS
366 * the resources needed by this library.
367 */
368 if (a_out->a_text > MAXTSIZ ||
369 a_out->a_data + bss_size > p->p_rlimit[RLIMIT_DATA].rlim_cur) {
370 error = ENOMEM;
371 goto cleanup;
372 }
419
373
420 /*
421 * prevent more writers
422 */
423 vp->v_flag |= VTEXT;
374 /* prevent more writers */
375 vp->v_flag |= VTEXT;
424
376
425 /*
426 * Check if file_offset page aligned,.
427 * Currently we cannot handle misalinged file offsets,
428 * and so we read in the entire image (what a waste).
429 */
430 if (file_offset & PAGE_MASK) {
431#ifdef DEBUG
432printf("uselib: Non page aligned binary %lu\n", file_offset);
433#endif
434 /*
377 /*
435 * Map text+data read/write/execute
378 * Check if file_offset page aligned. Currently we cannot handle
379 * misalinged file offsets, and so we read in the entire image
380 * (what a waste).
436 */
381 */
382 if (file_offset & PAGE_MASK) {
383#ifdef DEBUG
384 printf("uselib: Non page aligned binary %lu\n", file_offset);
385#endif
386 /* Map text+data read/write/execute */
437
387
438 /* a_entry is the load address and is page aligned */
439 vmaddr = trunc_page(a_out->a_entry);
388 /* a_entry is the load address and is page aligned */
389 vmaddr = trunc_page(a_out->a_entry);
440
390
441 /* get anon user mapping, read+write+execute */
442 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
443 a_out->a_text + a_out->a_data, FALSE,
444 VM_PROT_ALL, VM_PROT_ALL, 0);
445 if (error)
446 goto cleanup;
391 /* get anon user mapping, read+write+execute */
392 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
393 a_out->a_text + a_out->a_data, FALSE, VM_PROT_ALL,
394 VM_PROT_ALL, 0);
395 if (error)
396 goto cleanup;
447
397
448 /* map file into kernel_map */
449 error = vm_mmap(kernel_map, &buffer,
450 round_page(a_out->a_text + a_out->a_data + file_offset),
451 VM_PROT_READ, VM_PROT_READ, 0,
452 (caddr_t)vp, trunc_page(file_offset));
453 if (error)
454 goto cleanup;
398 /* map file into kernel_map */
399 error = vm_mmap(kernel_map, &buffer,
400 round_page(a_out->a_text + a_out->a_data + file_offset),
401 VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp,
402 trunc_page(file_offset));
403 if (error)
404 goto cleanup;
455
405
456 /* copy from kernel VM space to user space */
457 error = copyout((caddr_t)(void *)(uintptr_t)(buffer + file_offset),
458 (caddr_t)vmaddr, a_out->a_text + a_out->a_data);
406 /* copy from kernel VM space to user space */
407 error = copyout((caddr_t)(uintptr_t)(buffer + file_offset),
408 (caddr_t)vmaddr, a_out->a_text + a_out->a_data);
459
409
460 /* release temporary kernel space */
461 vm_map_remove(kernel_map, buffer,
462 buffer + round_page(a_out->a_text + a_out->a_data + file_offset));
410 /* release temporary kernel space */
411 vm_map_remove(kernel_map, buffer, buffer +
412 round_page(a_out->a_text + a_out->a_data + file_offset));
463
413
464 if (error)
465 goto cleanup;
466 }
467 else {
414 if (error)
415 goto cleanup;
416 } else {
468#ifdef DEBUG
417#ifdef DEBUG
469printf("uselib: Page aligned binary %lu\n", file_offset);
418 printf("uselib: Page aligned binary %lu\n", file_offset);
470#endif
419#endif
471 /*
472 * for QMAGIC, a_entry is 20 bytes beyond the load address
473 * to skip the executable header
474 */
475 vmaddr = trunc_page(a_out->a_entry);
420 /*
421 * for QMAGIC, a_entry is 20 bytes beyond the load address
422 * to skip the executable header
423 */
424 vmaddr = trunc_page(a_out->a_entry);
476
425
477 /*
478 * Map it all into the process's space as a single copy-on-write
479 * "data" segment.
480 */
481 error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr,
482 a_out->a_text + a_out->a_data,
483 VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED,
484 (caddr_t)vp, file_offset);
485 if (error)
486 goto cleanup;
487 }
426 /*
427 * Map it all into the process's space as a single
428 * copy-on-write "data" segment.
429 */
430 error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr,
431 a_out->a_text + a_out->a_data, VM_PROT_ALL, VM_PROT_ALL,
432 MAP_PRIVATE | MAP_FIXED, (caddr_t)vp, file_offset);
433 if (error)
434 goto cleanup;
435 }
488#ifdef DEBUG
436#ifdef DEBUG
489printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long*)vmaddr)[0], ((long*)vmaddr)[1]);
437 printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long*)vmaddr)[0],
438 ((long*)vmaddr)[1]);
490#endif
439#endif
491 if (bss_size != 0) {
492 /*
493 * Calculate BSS start address
494 */
495 vmaddr = trunc_page(a_out->a_entry) + a_out->a_text + a_out->a_data;
440 if (bss_size != 0) {
441 /* Calculate BSS start address */
442 vmaddr = trunc_page(a_out->a_entry) + a_out->a_text +
443 a_out->a_data;
496
444
497 /*
498 * allocate some 'anon' space
499 */
500 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
501 bss_size, FALSE,
502 VM_PROT_ALL, VM_PROT_ALL, 0);
503 if (error)
504 goto cleanup;
505 }
445 /* allocate some 'anon' space */
446 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
447 bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
448 if (error)
449 goto cleanup;
450 }
506
507cleanup:
451
452cleanup:
508 /*
509 * Unlock vnode if needed
510 */
511 if (locked)
512 VOP_UNLOCK(vp, 0, p);
453 /* Unlock vnode if needed */
454 if (locked)
455 VOP_UNLOCK(vp, 0, p);
513
456
514 /*
515 * Release the kernel mapping.
516 */
517 if (a_out)
518 vm_map_remove(kernel_map, (vm_offset_t)a_out, (vm_offset_t)a_out + PAGE_SIZE);
457 /* Release the kernel mapping. */
458 if (a_out)
459 vm_map_remove(kernel_map, (vm_offset_t)a_out,
460 (vm_offset_t)a_out + PAGE_SIZE);
519
461
520 return error;
462 return error;
521}
522
523int
463}
464
465int
524linux_newselect(struct proc *p, struct linux_newselect_args *args)
466linux_select(struct proc *p, struct linux_select_args *args)
525{
467{
526 struct select_args bsa;
527 struct timeval tv0, tv1, utv, *tvp;
528 caddr_t sg;
529 int error;
468 struct select_args bsa;
469 struct timeval tv0, tv1, utv, *tvp;
470 caddr_t sg;
471 int error;
530
531#ifdef DEBUG
472
473#ifdef DEBUG
532 if (ldebug(newselect))
533 printf(ARGS(newselect, "%d, %p, %p, %p, %p"),
534 args->nfds, (void *)args->readfds,
535 (void *)args->writefds, (void *)args->exceptfds,
536 (void *)args->timeout);
474 if (ldebug(select))
475 printf(ARGS(select, "%d, %p, %p, %p, %p"), args->nfds,
476 (void *)args->readfds, (void *)args->writefds,
477 (void *)args->exceptfds, (void *)args->timeout);
537#endif
478#endif
538 error = 0;
539 bsa.nd = args->nfds;
540 bsa.in = args->readfds;
541 bsa.ou = args->writefds;
542 bsa.ex = args->exceptfds;
543 bsa.tv = args->timeout;
544
479
545 /*
546 * Store current time for computation of the amount of
547 * time left.
548 */
549 if (args->timeout) {
550 if ((error = copyin(args->timeout, &utv, sizeof(utv))))
551 goto select_out;
480 error = 0;
481 bsa.nd = args->nfds;
482 bsa.in = args->readfds;
483 bsa.ou = args->writefds;
484 bsa.ex = args->exceptfds;
485 bsa.tv = (struct timeval *)args->timeout;
486
487 /*
488 * Store current time for computation of the amount of
489 * time left.
490 */
491 if (args->timeout) {
492 if ((error = copyin((caddr_t)args->timeout, &utv,
493 sizeof(utv))))
494 goto select_out;
552#ifdef DEBUG
495#ifdef DEBUG
553 if (ldebug(newselect))
554 printf(LMSG("incoming timeout (%ld/%ld)"),
555 utv.tv_sec, utv.tv_usec);
496 if (ldebug(select))
497 printf(LMSG("incoming timeout (%ld/%ld)"),
498 utv.tv_sec, utv.tv_usec);
556#endif
499#endif
557 if (itimerfix(&utv)) {
558 /*
559 * The timeval was invalid. Convert it to something
560 * valid that will act as it does under Linux.
561 */
562 sg = stackgap_init();
563 tvp = stackgap_alloc(&sg, sizeof(utv));
564 utv.tv_sec += utv.tv_usec / 1000000;
565 utv.tv_usec %= 1000000;
566 if (utv.tv_usec < 0) {
567 utv.tv_sec -= 1;
568 utv.tv_usec += 1000000;
569 }
570 if (utv.tv_sec < 0)
571 timevalclear(&utv);
572 if ((error = copyout(&utv, tvp, sizeof(utv))))
573 goto select_out;
574 bsa.tv = tvp;
500
501 if (itimerfix(&utv)) {
502 /*
503 * The timeval was invalid. Convert it to something
504 * valid that will act as it does under Linux.
505 */
506 sg = stackgap_init();
507 tvp = stackgap_alloc(&sg, sizeof(utv));
508 utv.tv_sec += utv.tv_usec / 1000000;
509 utv.tv_usec %= 1000000;
510 if (utv.tv_usec < 0) {
511 utv.tv_sec -= 1;
512 utv.tv_usec += 1000000;
513 }
514 if (utv.tv_sec < 0)
515 timevalclear(&utv);
516 if ((error = copyout(&utv, tvp, sizeof(utv))))
517 goto select_out;
518 bsa.tv = tvp;
519 }
520 microtime(&tv0);
575 }
521 }
576 microtime(&tv0);
577 }
578
522
579 error = select(p, &bsa);
523 error = select(p, &bsa);
580#ifdef DEBUG
524#ifdef DEBUG
581 if (ldebug(newselect))
525 if (ldebug(select))
582 printf(LMSG("real select returns %d"), error);
583#endif
526 printf(LMSG("real select returns %d"), error);
527#endif
528 if (error) {
529 /*
530 * See fs/select.c in the Linux kernel. Without this,
531 * Maelstrom doesn't work.
532 */
533 if (error == ERESTART)
534 error = EINTR;
535 goto select_out;
536 }
584
537
585 if (error) {
586 /*
587 * See fs/select.c in the Linux kernel. Without this,
588 * Maelstrom doesn't work.
589 */
590 if (error == ERESTART)
591 error = EINTR;
592 goto select_out;
593 }
594
595 if (args->timeout) {
596 if (p->p_retval[0]) {
597 /*
598 * Compute how much time was left of the timeout,
599 * by subtracting the current time and the time
600 * before we started the call, and subtracting
601 * that result from the user-supplied value.
602 */
603 microtime(&tv1);
604 timevalsub(&tv1, &tv0);
605 timevalsub(&utv, &tv1);
606 if (utv.tv_sec < 0)
607 timevalclear(&utv);
608 } else
609 timevalclear(&utv);
538 if (args->timeout) {
539 if (p->p_retval[0]) {
540 /*
541 * Compute how much time was left of the timeout,
542 * by subtracting the current time and the time
543 * before we started the call, and subtracting
544 * that result from the user-supplied value.
545 */
546 microtime(&tv1);
547 timevalsub(&tv1, &tv0);
548 timevalsub(&utv, &tv1);
549 if (utv.tv_sec < 0)
550 timevalclear(&utv);
551 } else
552 timevalclear(&utv);
610#ifdef DEBUG
553#ifdef DEBUG
611 if (ldebug(newselect))
612 printf(LMSG("outgoing timeout (%ld/%ld)"),
613 utv.tv_sec, utv.tv_usec);
554 if (ldebug(select))
555 printf(LMSG("outgoing timeout (%ld/%ld)"),
556 utv.tv_sec, utv.tv_usec);
614#endif
557#endif
615 if ((error = copyout(&utv, args->timeout, sizeof(utv))))
616 goto select_out;
617 }
558 if ((error = copyout(&utv, (caddr_t)args->timeout,
559 sizeof(utv))))
560 goto select_out;
561 }
618
619select_out:
620#ifdef DEBUG
562
563select_out:
564#ifdef DEBUG
621 if (ldebug(newselect))
622 printf(LMSG("newselect_out -> %d"), error);
565 if (ldebug(select))
566 printf(LMSG("select_out -> %d"), error);
623#endif
567#endif
624 return error;
568 return error;
625}
626
627int
628linux_getpgid(struct proc *p, struct linux_getpgid_args *args)
629{
569}
570
571int
572linux_getpgid(struct proc *p, struct linux_getpgid_args *args)
573{
630 struct proc *curp;
574 struct proc *curp;
631
632#ifdef DEBUG
633 if (ldebug(getpgid))
634 printf(ARGS(getpgid, "%d"), args->pid);
635#endif
575
576#ifdef DEBUG
577 if (ldebug(getpgid))
578 printf(ARGS(getpgid, "%d"), args->pid);
579#endif
636 if (args->pid != p->p_pid) {
637 if (!(curp = pfind(args->pid)))
638 return ESRCH;
639 p->p_retval[0] = curp->p_pgid;
640 PROC_UNLOCK(curp);
641 }
642 else
643 p->p_retval[0] = p->p_pgid;
644 return 0;
580
581 if (args->pid != p->p_pid) {
582 if (!(curp = pfind(args->pid)))
583 return ESRCH;
584 p->p_retval[0] = curp->p_pgid;
585 PROC_UNLOCK(curp);
586 } else
587 p->p_retval[0] = p->p_pgid;
588
589 return 0;
645}
646
647int
648linux_mremap(struct proc *p, struct linux_mremap_args *args)
649{
650 struct munmap_args /* {
651 void *addr;
652 size_t len;

--- 12 unchanged lines hidden (view full) ---

665 args->old_len = round_page(args->old_len);
666
667 if (args->new_len > args->old_len) {
668 p->p_retval[0] = 0;
669 return ENOMEM;
670 }
671
672 if (args->new_len < args->old_len) {
590}
591
592int
593linux_mremap(struct proc *p, struct linux_mremap_args *args)
594{
595 struct munmap_args /* {
596 void *addr;
597 size_t len;

--- 12 unchanged lines hidden (view full) ---

610 args->old_len = round_page(args->old_len);
611
612 if (args->new_len > args->old_len) {
613 p->p_retval[0] = 0;
614 return ENOMEM;
615 }
616
617 if (args->new_len < args->old_len) {
673 bsd_args.addr = args->addr + args->new_len;
618 bsd_args.addr = (caddr_t)(args->addr + args->new_len);
674 bsd_args.len = args->old_len - args->new_len;
675 error = munmap(p, &bsd_args);
676 }
677
678 p->p_retval[0] = error ? 0 : (u_long)args->addr;
679 return error;
680}
681
682int
683linux_msync(struct proc *p, struct linux_msync_args *args)
684{
685 struct msync_args bsd_args;
686
619 bsd_args.len = args->old_len - args->new_len;
620 error = munmap(p, &bsd_args);
621 }
622
623 p->p_retval[0] = error ? 0 : (u_long)args->addr;
624 return error;
625}
626
627int
628linux_msync(struct proc *p, struct linux_msync_args *args)
629{
630 struct msync_args bsd_args;
631
687 bsd_args.addr = args->addr;
632 bsd_args.addr = (caddr_t)args->addr;
688 bsd_args.len = args->len;
689 bsd_args.flags = 0; /* XXX ignore */
690
691 return msync(p, &bsd_args);
692}
693
694#ifndef __alpha__
695int
696linux_time(struct proc *p, struct linux_time_args *args)
697{
633 bsd_args.len = args->len;
634 bsd_args.flags = 0; /* XXX ignore */
635
636 return msync(p, &bsd_args);
637}
638
639#ifndef __alpha__
640int
641linux_time(struct proc *p, struct linux_time_args *args)
642{
698 struct timeval tv;
699 linux_time_t tm;
700 int error;
643 struct timeval tv;
644 l_time_t tm;
645 int error;
701
702#ifdef DEBUG
703 if (ldebug(time))
704 printf(ARGS(time, "*"));
705#endif
646
647#ifdef DEBUG
648 if (ldebug(time))
649 printf(ARGS(time, "*"));
650#endif
706 microtime(&tv);
707 tm = tv.tv_sec;
708 if (args->tm && (error = copyout(&tm, args->tm, sizeof(linux_time_t))))
709 return error;
710 p->p_retval[0] = tm;
711 return 0;
651
652 microtime(&tv);
653 tm = tv.tv_sec;
654 if (args->tm && (error = copyout(&tm, (caddr_t)args->tm, sizeof(tm))))
655 return error;
656 p->p_retval[0] = tm;
657 return 0;
712}
713#endif /*!__alpha__*/
714
658}
659#endif /*!__alpha__*/
660
715struct linux_times_argv {
716 long tms_utime;
717 long tms_stime;
718 long tms_cutime;
719 long tms_cstime;
661struct l_times_argv {
662 l_long tms_utime;
663 l_long tms_stime;
664 l_long tms_cutime;
665 l_long tms_cstime;
720};
721
722#ifdef __alpha__
723#define CLK_TCK 1024 /* Linux uses 1024 on alpha */
724#else
725#define CLK_TCK 100 /* Linux uses 100 */
726#endif
727
728#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
729
730int
731linux_times(struct proc *p, struct linux_times_args *args)
732{
666};
667
668#ifdef __alpha__
669#define CLK_TCK 1024 /* Linux uses 1024 on alpha */
670#else
671#define CLK_TCK 100 /* Linux uses 100 */
672#endif
673
674#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
675
676int
677linux_times(struct proc *p, struct linux_times_args *args)
678{
733 struct timeval tv;
734 struct linux_times_argv tms;
735 struct rusage ru;
736 int error;
679 struct timeval tv;
680 struct l_times_argv tms;
681 struct rusage ru;
682 int error;
737
738#ifdef DEBUG
739 if (ldebug(times))
740 printf(ARGS(times, "*"));
741#endif
683
684#ifdef DEBUG
685 if (ldebug(times))
686 printf(ARGS(times, "*"));
687#endif
742 mtx_lock_spin(&sched_lock);
743 calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
744 mtx_unlock_spin(&sched_lock);
745
688
746 tms.tms_utime = CONVTCK(ru.ru_utime);
747 tms.tms_stime = CONVTCK(ru.ru_stime);
689 mtx_lock_spin(&sched_lock);
690 calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
691 mtx_unlock_spin(&sched_lock);
748
692
749 tms.tms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime);
750 tms.tms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime);
693 tms.tms_utime = CONVTCK(ru.ru_utime);
694 tms.tms_stime = CONVTCK(ru.ru_stime);
751
695
752 if ((error = copyout((caddr_t)&tms, (caddr_t)args->buf,
753 sizeof(struct linux_times_argv))))
754 return error;
696 tms.tms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime);
697 tms.tms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime);
755
698
756 microuptime(&tv);
757 p->p_retval[0] = (int)CONVTCK(tv);
758 return 0;
699 if ((error = copyout(&tms, (caddr_t)args->buf, sizeof(tms))))
700 return error;
701
702 microuptime(&tv);
703 p->p_retval[0] = (int)CONVTCK(tv);
704 return 0;
759}
760
761int
762linux_newuname(struct proc *p, struct linux_newuname_args *args)
763{
705}
706
707int
708linux_newuname(struct proc *p, struct linux_newuname_args *args)
709{
764 struct linux_new_utsname utsname;
710 struct l_new_utsname utsname;
765 char *osrelease, *osname;
766
767#ifdef DEBUG
768 if (ldebug(newuname))
769 printf(ARGS(newuname, "*"));
770#endif
771
772 osname = linux_get_osname(p);
773 osrelease = linux_get_osrelease(p);
774
711 char *osrelease, *osname;
712
713#ifdef DEBUG
714 if (ldebug(newuname))
715 printf(ARGS(newuname, "*"));
716#endif
717
718 osname = linux_get_osname(p);
719 osrelease = linux_get_osrelease(p);
720
775 bzero(&utsname, sizeof(struct linux_new_utsname));
721 bzero(&utsname, sizeof(utsname));
776 strncpy(utsname.sysname, osname, LINUX_MAX_UTSNAME-1);
777 strncpy(utsname.nodename, hostname, LINUX_MAX_UTSNAME-1);
778 strncpy(utsname.release, osrelease, LINUX_MAX_UTSNAME-1);
779 strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1);
780 strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1);
781 strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1);
782
722 strncpy(utsname.sysname, osname, LINUX_MAX_UTSNAME-1);
723 strncpy(utsname.nodename, hostname, LINUX_MAX_UTSNAME-1);
724 strncpy(utsname.release, osrelease, LINUX_MAX_UTSNAME-1);
725 strncpy(utsname.version, version, LINUX_MAX_UTSNAME-1);
726 strncpy(utsname.machine, machine, LINUX_MAX_UTSNAME-1);
727 strncpy(utsname.domainname, domainname, LINUX_MAX_UTSNAME-1);
728
783 return (copyout((caddr_t)&utsname, (caddr_t)args->buf,
784 sizeof(struct linux_new_utsname)));
729 return (copyout(&utsname, (caddr_t)args->buf, sizeof(utsname)));
785}
786
730}
731
787struct linux_utimbuf {
788 linux_time_t l_actime;
789 linux_time_t l_modtime;
732#if defined(__i386__)
733struct l_utimbuf {
734 l_time_t l_actime;
735 l_time_t l_modtime;
790};
791
792int
793linux_utime(struct proc *p, struct linux_utime_args *args)
794{
736};
737
738int
739linux_utime(struct proc *p, struct linux_utime_args *args)
740{
795 struct utimes_args /* {
796 char *path;
797 struct timeval *tptr;
798 } */ bsdutimes;
799 struct timeval tv[2], *tvp;
800 struct linux_utimbuf lut;
801 int error;
802 caddr_t sg;
741 struct utimes_args /* {
742 char *path;
743 struct timeval *tptr;
744 } */ bsdutimes;
745 struct timeval tv[2], *tvp;
746 struct l_utimbuf lut;
747 int error;
748 caddr_t sg;
803
749
804 sg = stackgap_init();
805 CHECKALTEXIST(p, &sg, args->fname);
750 sg = stackgap_init();
751 CHECKALTEXIST(p, &sg, args->fname);
806
807#ifdef DEBUG
808 if (ldebug(utime))
809 printf(ARGS(utime, "%s, *"), args->fname);
810#endif
752
753#ifdef DEBUG
754 if (ldebug(utime))
755 printf(ARGS(utime, "%s, *"), args->fname);
756#endif
811 if (args->times) {
812 if ((error = copyin(args->times, &lut, sizeof lut)))
813 return error;
814 tv[0].tv_sec = lut.l_actime;
815 tv[0].tv_usec = 0;
816 tv[1].tv_sec = lut.l_modtime;
817 tv[1].tv_usec = 0;
818 /* so that utimes can copyin */
819 tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv));
820 if (tvp == NULL)
821 return (ENAMETOOLONG);
822 if ((error = copyout(tv, tvp, sizeof(tv))))
823 return error;
824 bsdutimes.tptr = tvp;
825 } else
826 bsdutimes.tptr = NULL;
827
757
828 bsdutimes.path = args->fname;
829 return utimes(p, &bsdutimes);
758 if (args->times) {
759 if ((error = copyin((caddr_t)args->times, &lut, sizeof lut)))
760 return error;
761 tv[0].tv_sec = lut.l_actime;
762 tv[0].tv_usec = 0;
763 tv[1].tv_sec = lut.l_modtime;
764 tv[1].tv_usec = 0;
765 /* so that utimes can copyin */
766 tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv));
767 if (tvp == NULL)
768 return (ENAMETOOLONG);
769 if ((error = copyout(tv, tvp, sizeof(tv))))
770 return error;
771 bsdutimes.tptr = tvp;
772 } else
773 bsdutimes.tptr = NULL;
774
775 bsdutimes.path = args->fname;
776 return utimes(p, &bsdutimes);
830}
777}
778#endif /* __i386__ */
831
832#define __WCLONE 0x80000000
833
834#ifndef __alpha__
835int
836linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
837{
779
780#define __WCLONE 0x80000000
781
782#ifndef __alpha__
783int
784linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
785{
838 struct wait_args /* {
839 int pid;
840 int *status;
841 int options;
842 struct rusage *rusage;
843 } */ tmp;
844 int error, tmpstat;
786 struct wait_args /* {
787 int pid;
788 int *status;
789 int options;
790 struct rusage *rusage;
791 } */ tmp;
792 int error, tmpstat;
845
846#ifdef DEBUG
847 if (ldebug(waitpid))
848 printf(ARGS(waitpid, "%d, %p, %d"),
849 args->pid, (void *)args->status, args->options);
850#endif
793
794#ifdef DEBUG
795 if (ldebug(waitpid))
796 printf(ARGS(waitpid, "%d, %p, %d"),
797 args->pid, (void *)args->status, args->options);
798#endif
851 tmp.pid = args->pid;
852 tmp.status = args->status;
853 tmp.options = (args->options & (WNOHANG | WUNTRACED));
854 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
855 if (args->options & __WCLONE)
856 tmp.options |= WLINUXCLONE;
857 tmp.rusage = NULL;
858
799
859 if ((error = wait4(p, &tmp)) != 0)
860 return error;
800 tmp.pid = args->pid;
801 tmp.status = args->status;
802 tmp.options = (args->options & (WNOHANG | WUNTRACED));
803 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
804 if (args->options & __WCLONE)
805 tmp.options |= WLINUXCLONE;
806 tmp.rusage = NULL;
861
807
862 if (args->status) {
863 if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0)
864 return error;
865 tmpstat &= 0xffff;
866 if (WIFSIGNALED(tmpstat))
867 tmpstat = (tmpstat & 0xffffff80) |
868 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
869 else if (WIFSTOPPED(tmpstat))
870 tmpstat = (tmpstat & 0xffff00ff) |
871 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8);
872 return copyout(&tmpstat, args->status, sizeof(int));
873 } else
808 if ((error = wait4(p, &tmp)) != 0)
809 return error;
810
811 if (args->status) {
812 if ((error = copyin((caddr_t)args->status, &tmpstat,
813 sizeof(int))) != 0)
814 return error;
815 tmpstat &= 0xffff;
816 if (WIFSIGNALED(tmpstat))
817 tmpstat = (tmpstat & 0xffffff80) |
818 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
819 else if (WIFSTOPPED(tmpstat))
820 tmpstat = (tmpstat & 0xffff00ff) |
821 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8);
822 return copyout(&tmpstat, (caddr_t)args->status, sizeof(int));
823 }
824
874 return 0;
875}
876#endif /*!__alpha__*/
877
878int
879linux_wait4(struct proc *p, struct linux_wait4_args *args)
880{
825 return 0;
826}
827#endif /*!__alpha__*/
828
829int
830linux_wait4(struct proc *p, struct linux_wait4_args *args)
831{
881 struct wait_args /* {
882 int pid;
883 int *status;
884 int options;
885 struct rusage *rusage;
886 } */ tmp;
887 int error, tmpstat;
832 struct wait_args /* {
833 int pid;
834 int *status;
835 int options;
836 struct rusage *rusage;
837 } */ tmp;
838 int error, tmpstat;
888
889#ifdef DEBUG
890 if (ldebug(wait4))
891 printf(ARGS(wait4, "%d, %p, %d, %p"),
892 args->pid, (void *)args->status, args->options,
893 (void *)args->rusage);
894#endif
839
840#ifdef DEBUG
841 if (ldebug(wait4))
842 printf(ARGS(wait4, "%d, %p, %d, %p"),
843 args->pid, (void *)args->status, args->options,
844 (void *)args->rusage);
845#endif
895 tmp.pid = args->pid;
896 tmp.status = args->status;
897 tmp.options = (args->options & (WNOHANG | WUNTRACED));
898 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
899 if (args->options & __WCLONE)
900 tmp.options |= WLINUXCLONE;
901 tmp.rusage = args->rusage;
902
846
903 if ((error = wait4(p, &tmp)) != 0)
904 return error;
847 tmp.pid = args->pid;
848 tmp.status = args->status;
849 tmp.options = (args->options & (WNOHANG | WUNTRACED));
850 /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
851 if (args->options & __WCLONE)
852 tmp.options |= WLINUXCLONE;
853 tmp.rusage = (struct rusage *)args->rusage;
905
854
906 SIGDELSET(p->p_siglist, SIGCHLD);
855 if ((error = wait4(p, &tmp)) != 0)
856 return error;
907
857
908 if (args->status) {
909 if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0)
910 return error;
911 tmpstat &= 0xffff;
912 if (WIFSIGNALED(tmpstat))
913 tmpstat = (tmpstat & 0xffffff80) |
914 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
915 else if (WIFSTOPPED(tmpstat))
916 tmpstat = (tmpstat & 0xffff00ff) |
917 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8);
918 return copyout(&tmpstat, args->status, sizeof(int));
919 } else
858 SIGDELSET(p->p_siglist, SIGCHLD);
859
860 if (args->status) {
861 if ((error = copyin((caddr_t)args->status, &tmpstat,
862 sizeof(int))) != 0)
863 return error;
864 tmpstat &= 0xffff;
865 if (WIFSIGNALED(tmpstat))
866 tmpstat = (tmpstat & 0xffffff80) |
867 BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
868 else if (WIFSTOPPED(tmpstat))
869 tmpstat = (tmpstat & 0xffff00ff) |
870 (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8);
871 return copyout(&tmpstat, (caddr_t)args->status, sizeof(int));
872 }
873
920 return 0;
921}
922
923int
924linux_mknod(struct proc *p, struct linux_mknod_args *args)
925{
926 caddr_t sg;
927 struct mknod_args bsd_mknod;

--- 52 unchanged lines hidden (view full) ---

980 int error;
981
982#ifdef DEBUG
983 if (ldebug(setitimer))
984 printf(ARGS(setitimer, "%p, %p"),
985 (void *)args->itv, (void *)args->oitv);
986#endif
987 bsa.which = args->which;
874 return 0;
875}
876
877int
878linux_mknod(struct proc *p, struct linux_mknod_args *args)
879{
880 caddr_t sg;
881 struct mknod_args bsd_mknod;

--- 52 unchanged lines hidden (view full) ---

934 int error;
935
936#ifdef DEBUG
937 if (ldebug(setitimer))
938 printf(ARGS(setitimer, "%p, %p"),
939 (void *)args->itv, (void *)args->oitv);
940#endif
941 bsa.which = args->which;
988 bsa.itv = args->itv;
989 bsa.oitv = args->oitv;
942 bsa.itv = (struct itimerval *)args->itv;
943 bsa.oitv = (struct itimerval *)args->oitv;
990 if (args->itv) {
944 if (args->itv) {
991 if ((error = copyin((caddr_t)args->itv, (caddr_t)&foo,
992 sizeof(foo))))
945 if ((error = copyin((caddr_t)args->itv, &foo, sizeof(foo))))
993 return error;
994#ifdef DEBUG
995 if (ldebug(setitimer)) {
996 printf("setitimer: value: sec: %ld, usec: %ld\n",
997 foo.it_value.tv_sec, foo.it_value.tv_usec);
998 printf("setitimer: interval: sec: %ld, usec: %ld\n",
999 foo.it_interval.tv_sec, foo.it_interval.tv_usec);
1000 }

--- 6 unchanged lines hidden (view full) ---

1007linux_getitimer(struct proc *p, struct linux_getitimer_args *args)
1008{
1009 struct getitimer_args bsa;
1010#ifdef DEBUG
1011 if (ldebug(getitimer))
1012 printf(ARGS(getitimer, "%p"), (void *)args->itv);
1013#endif
1014 bsa.which = args->which;
946 return error;
947#ifdef DEBUG
948 if (ldebug(setitimer)) {
949 printf("setitimer: value: sec: %ld, usec: %ld\n",
950 foo.it_value.tv_sec, foo.it_value.tv_usec);
951 printf("setitimer: interval: sec: %ld, usec: %ld\n",
952 foo.it_interval.tv_sec, foo.it_interval.tv_usec);
953 }

--- 6 unchanged lines hidden (view full) ---

960linux_getitimer(struct proc *p, struct linux_getitimer_args *args)
961{
962 struct getitimer_args bsa;
963#ifdef DEBUG
964 if (ldebug(getitimer))
965 printf(ARGS(getitimer, "%p"), (void *)args->itv);
966#endif
967 bsa.which = args->which;
1015 bsa.itv = args->itv;
968 bsa.itv = (struct itimerval *)args->itv;
1016 return getitimer(p, &bsa);
1017}
1018
1019#ifndef __alpha__
1020int
1021linux_nice(struct proc *p, struct linux_nice_args *args)
1022{
1023 struct setpriority_args bsd_args;
1024
1025 bsd_args.which = PRIO_PROCESS;
1026 bsd_args.who = 0; /* current process */
1027 bsd_args.prio = args->inc;
1028 return setpriority(p, &bsd_args);
1029}
1030#endif /*!__alpha__*/
1031
1032int
969 return getitimer(p, &bsa);
970}
971
972#ifndef __alpha__
973int
974linux_nice(struct proc *p, struct linux_nice_args *args)
975{
976 struct setpriority_args bsd_args;
977
978 bsd_args.which = PRIO_PROCESS;
979 bsd_args.who = 0; /* current process */
980 bsd_args.prio = args->inc;
981 return setpriority(p, &bsd_args);
982}
983#endif /*!__alpha__*/
984
985int
1033linux_setgroups(p, uap)
1034 struct proc *p;
1035 struct linux_setgroups_args *uap;
986linux_setgroups(struct proc *p, struct linux_setgroups_args *args)
1036{
1037 struct ucred *newcred, *oldcred;
987{
988 struct ucred *newcred, *oldcred;
1038 linux_gid_t linux_gidset[NGROUPS];
989 l_gid_t linux_gidset[NGROUPS];
1039 gid_t *bsd_gidset;
1040 int ngrp, error;
1041
990 gid_t *bsd_gidset;
991 int ngrp, error;
992
1042 ngrp = uap->gidsetsize;
993 ngrp = args->gidsetsize;
1043 oldcred = p->p_ucred;
1044
1045 /*
1046 * cr_groups[0] holds egid. Setting the whole set from
1047 * the supplied set will cause egid to be changed too.
1048 * Keep cr_groups[0] unchanged to prevent that.
1049 */
1050
1051 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
1052 return (error);
1053
1054 if (ngrp >= NGROUPS)
1055 return (EINVAL);
1056
1057 newcred = crdup(oldcred);
1058 if (ngrp > 0) {
994 oldcred = p->p_ucred;
995
996 /*
997 * cr_groups[0] holds egid. Setting the whole set from
998 * the supplied set will cause egid to be changed too.
999 * Keep cr_groups[0] unchanged to prevent that.
1000 */
1001
1002 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
1003 return (error);
1004
1005 if (ngrp >= NGROUPS)
1006 return (EINVAL);
1007
1008 newcred = crdup(oldcred);
1009 if (ngrp > 0) {
1059 error = copyin((caddr_t)uap->gidset, (caddr_t)linux_gidset,
1060 ngrp * sizeof(linux_gid_t));
1010 error = copyin((caddr_t)args->grouplist, linux_gidset,
1011 ngrp * sizeof(l_gid_t));
1061 if (error)
1062 return (error);
1063
1064 newcred->cr_ngroups = ngrp + 1;
1065
1066 bsd_gidset = newcred->cr_groups;
1067 ngrp--;
1068 while (ngrp >= 0) {

--- 6 unchanged lines hidden (view full) ---

1075
1076 setsugid(p);
1077 p->p_ucred = newcred;
1078 crfree(oldcred);
1079 return (0);
1080}
1081
1082int
1012 if (error)
1013 return (error);
1014
1015 newcred->cr_ngroups = ngrp + 1;
1016
1017 bsd_gidset = newcred->cr_groups;
1018 ngrp--;
1019 while (ngrp >= 0) {

--- 6 unchanged lines hidden (view full) ---

1026
1027 setsugid(p);
1028 p->p_ucred = newcred;
1029 crfree(oldcred);
1030 return (0);
1031}
1032
1033int
1083linux_getgroups(p, uap)
1084 struct proc *p;
1085 struct linux_getgroups_args *uap;
1034linux_getgroups(struct proc *p, struct linux_getgroups_args *args)
1086{
1087 struct ucred *cred;
1035{
1036 struct ucred *cred;
1088 linux_gid_t linux_gidset[NGROUPS];
1037 l_gid_t linux_gidset[NGROUPS];
1089 gid_t *bsd_gidset;
1090 int bsd_gidsetsz, ngrp, error;
1091
1092 cred = p->p_ucred;
1093 bsd_gidset = cred->cr_groups;
1094 bsd_gidsetsz = cred->cr_ngroups - 1;
1095
1096 /*
1097 * cr_groups[0] holds egid. Returning the whole set
1098 * here will cause a duplicate. Exclude cr_groups[0]
1099 * to prevent that.
1100 */
1101
1038 gid_t *bsd_gidset;
1039 int bsd_gidsetsz, ngrp, error;
1040
1041 cred = p->p_ucred;
1042 bsd_gidset = cred->cr_groups;
1043 bsd_gidsetsz = cred->cr_ngroups - 1;
1044
1045 /*
1046 * cr_groups[0] holds egid. Returning the whole set
1047 * here will cause a duplicate. Exclude cr_groups[0]
1048 * to prevent that.
1049 */
1050
1102 if ((ngrp = uap->gidsetsize) == 0) {
1051 if ((ngrp = args->gidsetsize) == 0) {
1103 p->p_retval[0] = bsd_gidsetsz;
1104 return (0);
1105 }
1106
1107 if (ngrp < bsd_gidsetsz)
1108 return (EINVAL);
1109
1110 ngrp = 0;
1111 while (ngrp < bsd_gidsetsz) {
1112 linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
1113 ngrp++;
1114 }
1115
1052 p->p_retval[0] = bsd_gidsetsz;
1053 return (0);
1054 }
1055
1056 if (ngrp < bsd_gidsetsz)
1057 return (EINVAL);
1058
1059 ngrp = 0;
1060 while (ngrp < bsd_gidsetsz) {
1061 linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
1062 ngrp++;
1063 }
1064
1116 if ((error = copyout((caddr_t)linux_gidset, (caddr_t)uap->gidset,
1117 ngrp * sizeof(linux_gid_t))))
1065 if ((error = copyout(linux_gidset, (caddr_t)args->grouplist,
1066 ngrp * sizeof(l_gid_t))))
1118 return (error);
1119
1120 p->p_retval[0] = ngrp;
1121 return (0);
1122}
1123
1124#ifndef __alpha__
1125int
1067 return (error);
1068
1069 p->p_retval[0] = ngrp;
1070 return (0);
1071}
1072
1073#ifndef __alpha__
1074int
1126linux_setrlimit(p, uap)
1127 struct proc *p;
1128 struct linux_setrlimit_args *uap;
1075linux_setrlimit(struct proc *p, struct linux_setrlimit_args *args)
1129{
1130 struct __setrlimit_args bsd;
1076{
1077 struct __setrlimit_args bsd;
1131 struct linux_rlimit rlim;
1078 struct l_rlimit rlim;
1132 int error;
1133 caddr_t sg = stackgap_init();
1134
1135#ifdef DEBUG
1136 if (ldebug(setrlimit))
1137 printf(ARGS(setrlimit, "%d, %p"),
1079 int error;
1080 caddr_t sg = stackgap_init();
1081
1082#ifdef DEBUG
1083 if (ldebug(setrlimit))
1084 printf(ARGS(setrlimit, "%d, %p"),
1138 uap->resource, (void *)uap->rlim);
1085 args->resource, (void *)args->rlim);
1139#endif
1140
1086#endif
1087
1141 if (uap->resource >= LINUX_RLIM_NLIMITS)
1088 if (args->resource >= LINUX_RLIM_NLIMITS)
1142 return (EINVAL);
1143
1089 return (EINVAL);
1090
1144 bsd.which = linux_to_bsd_resource[uap->resource];
1091 bsd.which = linux_to_bsd_resource[args->resource];
1145 if (bsd.which == -1)
1146 return (EINVAL);
1147
1092 if (bsd.which == -1)
1093 return (EINVAL);
1094
1148 error = copyin(uap->rlim, &rlim, sizeof(rlim));
1095 error = copyin((caddr_t)args->rlim, &rlim, sizeof(rlim));
1149 if (error)
1150 return (error);
1151
1152 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit));
1153 bsd.rlp->rlim_cur = (rlim_t)rlim.rlim_cur;
1154 bsd.rlp->rlim_max = (rlim_t)rlim.rlim_max;
1155 return (setrlimit(p, &bsd));
1156}
1157
1158int
1096 if (error)
1097 return (error);
1098
1099 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit));
1100 bsd.rlp->rlim_cur = (rlim_t)rlim.rlim_cur;
1101 bsd.rlp->rlim_max = (rlim_t)rlim.rlim_max;
1102 return (setrlimit(p, &bsd));
1103}
1104
1105int
1159linux_getrlimit(p, uap)
1160 struct proc *p;
1161 struct linux_getrlimit_args *uap;
1106linux_old_getrlimit(struct proc *p, struct linux_old_getrlimit_args *args)
1162{
1163 struct __getrlimit_args bsd;
1107{
1108 struct __getrlimit_args bsd;
1164 struct linux_rlimit rlim;
1109 struct l_rlimit rlim;
1165 int error;
1166 caddr_t sg = stackgap_init();
1167
1168#ifdef DEBUG
1110 int error;
1111 caddr_t sg = stackgap_init();
1112
1113#ifdef DEBUG
1169 if (ldebug(getrlimit))
1170 printf(ARGS(getrlimit, "%d, %p"),
1171 uap->resource, (void *)uap->rlim);
1114 if (ldebug(old_getrlimit))
1115 printf(ARGS(old_getrlimit, "%d, %p"),
1116 args->resource, (void *)args->rlim);
1172#endif
1173
1117#endif
1118
1174 if (uap->resource >= LINUX_RLIM_NLIMITS)
1119 if (args->resource >= LINUX_RLIM_NLIMITS)
1175 return (EINVAL);
1176
1120 return (EINVAL);
1121
1177 bsd.which = linux_to_bsd_resource[uap->resource];
1122 bsd.which = linux_to_bsd_resource[args->resource];
1178 if (bsd.which == -1)
1179 return (EINVAL);
1180
1181 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit));
1182 error = getrlimit(p, &bsd);
1183 if (error)
1184 return (error);
1185
1186 rlim.rlim_cur = (unsigned long)bsd.rlp->rlim_cur;
1187 if (rlim.rlim_cur == ULONG_MAX)
1188 rlim.rlim_cur = LONG_MAX;
1189 rlim.rlim_max = (unsigned long)bsd.rlp->rlim_max;
1190 if (rlim.rlim_max == ULONG_MAX)
1191 rlim.rlim_max = LONG_MAX;
1123 if (bsd.which == -1)
1124 return (EINVAL);
1125
1126 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit));
1127 error = getrlimit(p, &bsd);
1128 if (error)
1129 return (error);
1130
1131 rlim.rlim_cur = (unsigned long)bsd.rlp->rlim_cur;
1132 if (rlim.rlim_cur == ULONG_MAX)
1133 rlim.rlim_cur = LONG_MAX;
1134 rlim.rlim_max = (unsigned long)bsd.rlp->rlim_max;
1135 if (rlim.rlim_max == ULONG_MAX)
1136 rlim.rlim_max = LONG_MAX;
1192 return (copyout(&rlim, uap->rlim, sizeof(rlim)));
1137 return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim)));
1193}
1138}
1139
1140int
1141linux_getrlimit(struct proc *p, struct linux_getrlimit_args *args)
1142{
1143 struct __getrlimit_args bsd;
1144 struct l_rlimit rlim;
1145 int error;
1146 caddr_t sg = stackgap_init();
1147
1148#ifdef DEBUG
1149 if (ldebug(getrlimit))
1150 printf(ARGS(getrlimit, "%d, %p"),
1151 args->resource, (void *)args->rlim);
1152#endif
1153
1154 if (args->resource >= LINUX_RLIM_NLIMITS)
1155 return (EINVAL);
1156
1157 bsd.which = linux_to_bsd_resource[args->resource];
1158 if (bsd.which == -1)
1159 return (EINVAL);
1160
1161 bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit));
1162 error = getrlimit(p, &bsd);
1163 if (error)
1164 return (error);
1165
1166 rlim.rlim_cur = (l_ulong)bsd.rlp->rlim_cur;
1167 rlim.rlim_max = (l_ulong)bsd.rlp->rlim_max;
1168 return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim)));
1169}
1194#endif /*!__alpha__*/
1195
1196int
1170#endif /*!__alpha__*/
1171
1172int
1197linux_sched_setscheduler(p, uap)
1198 struct proc *p;
1199 struct linux_sched_setscheduler_args *uap;
1173linux_sched_setscheduler(struct proc *p,
1174 struct linux_sched_setscheduler_args *args)
1200{
1201 struct sched_setscheduler_args bsd;
1202
1203#ifdef DEBUG
1204 if (ldebug(sched_setscheduler))
1205 printf(ARGS(sched_setscheduler, "%d, %d, %p"),
1175{
1176 struct sched_setscheduler_args bsd;
1177
1178#ifdef DEBUG
1179 if (ldebug(sched_setscheduler))
1180 printf(ARGS(sched_setscheduler, "%d, %d, %p"),
1206 uap->pid, uap->policy, (const void *)uap->param);
1181 args->pid, args->policy, (const void *)args->param);
1207#endif
1208
1182#endif
1183
1209 switch (uap->policy) {
1184 switch (args->policy) {
1210 case LINUX_SCHED_OTHER:
1211 bsd.policy = SCHED_OTHER;
1212 break;
1213 case LINUX_SCHED_FIFO:
1214 bsd.policy = SCHED_FIFO;
1215 break;
1216 case LINUX_SCHED_RR:
1217 bsd.policy = SCHED_RR;
1218 break;
1219 default:
1220 return EINVAL;
1221 }
1222
1185 case LINUX_SCHED_OTHER:
1186 bsd.policy = SCHED_OTHER;
1187 break;
1188 case LINUX_SCHED_FIFO:
1189 bsd.policy = SCHED_FIFO;
1190 break;
1191 case LINUX_SCHED_RR:
1192 bsd.policy = SCHED_RR;
1193 break;
1194 default:
1195 return EINVAL;
1196 }
1197
1223 bsd.pid = uap->pid;
1224 bsd.param = uap->param;
1198 bsd.pid = args->pid;
1199 bsd.param = (struct sched_param *)args->param;
1225 return sched_setscheduler(p, &bsd);
1226}
1227
1228int
1200 return sched_setscheduler(p, &bsd);
1201}
1202
1203int
1229linux_sched_getscheduler(p, uap)
1230 struct proc *p;
1231 struct linux_sched_getscheduler_args *uap;
1204linux_sched_getscheduler(struct proc *p,
1205 struct linux_sched_getscheduler_args *args)
1232{
1233 struct sched_getscheduler_args bsd;
1234 int error;
1235
1236#ifdef DEBUG
1237 if (ldebug(sched_getscheduler))
1206{
1207 struct sched_getscheduler_args bsd;
1208 int error;
1209
1210#ifdef DEBUG
1211 if (ldebug(sched_getscheduler))
1238 printf(ARGS(sched_getscheduler, "%d"), uap->pid);
1212 printf(ARGS(sched_getscheduler, "%d"), args->pid);
1239#endif
1240
1213#endif
1214
1241 bsd.pid = uap->pid;
1215 bsd.pid = args->pid;
1242 error = sched_getscheduler(p, &bsd);
1243
1244 switch (p->p_retval[0]) {
1245 case SCHED_OTHER:
1246 p->p_retval[0] = LINUX_SCHED_OTHER;
1247 break;
1248 case SCHED_FIFO:
1249 p->p_retval[0] = LINUX_SCHED_FIFO;
1250 break;
1251 case SCHED_RR:
1252 p->p_retval[0] = LINUX_SCHED_RR;
1253 break;
1254 }
1255
1256 return error;
1257}
1258
1259int
1216 error = sched_getscheduler(p, &bsd);
1217
1218 switch (p->p_retval[0]) {
1219 case SCHED_OTHER:
1220 p->p_retval[0] = LINUX_SCHED_OTHER;
1221 break;
1222 case SCHED_FIFO:
1223 p->p_retval[0] = LINUX_SCHED_FIFO;
1224 break;
1225 case SCHED_RR:
1226 p->p_retval[0] = LINUX_SCHED_RR;
1227 break;
1228 }
1229
1230 return error;
1231}
1232
1233int
1260linux_sched_get_priority_max(p, uap)
1261 struct proc *p;
1262 struct linux_sched_get_priority_max_args *uap;
1234linux_sched_get_priority_max(struct proc *p,
1235 struct linux_sched_get_priority_max_args *args)
1263{
1264 struct sched_get_priority_max_args bsd;
1265
1266#ifdef DEBUG
1267 if (ldebug(sched_get_priority_max))
1236{
1237 struct sched_get_priority_max_args bsd;
1238
1239#ifdef DEBUG
1240 if (ldebug(sched_get_priority_max))
1268 printf(ARGS(sched_get_priority_max, "%d"), uap->policy);
1241 printf(ARGS(sched_get_priority_max, "%d"), args->policy);
1269#endif
1270
1242#endif
1243
1271 switch (uap->policy) {
1244 switch (args->policy) {
1272 case LINUX_SCHED_OTHER:
1273 bsd.policy = SCHED_OTHER;
1274 break;
1275 case LINUX_SCHED_FIFO:
1276 bsd.policy = SCHED_FIFO;
1277 break;
1278 case LINUX_SCHED_RR:
1279 bsd.policy = SCHED_RR;
1280 break;
1281 default:
1282 return EINVAL;
1283 }
1284 return sched_get_priority_max(p, &bsd);
1285}
1286
1287int
1245 case LINUX_SCHED_OTHER:
1246 bsd.policy = SCHED_OTHER;
1247 break;
1248 case LINUX_SCHED_FIFO:
1249 bsd.policy = SCHED_FIFO;
1250 break;
1251 case LINUX_SCHED_RR:
1252 bsd.policy = SCHED_RR;
1253 break;
1254 default:
1255 return EINVAL;
1256 }
1257 return sched_get_priority_max(p, &bsd);
1258}
1259
1260int
1288linux_sched_get_priority_min(p, uap)
1289 struct proc *p;
1290 struct linux_sched_get_priority_min_args *uap;
1261linux_sched_get_priority_min(struct proc *p,
1262 struct linux_sched_get_priority_min_args *args)
1291{
1292 struct sched_get_priority_min_args bsd;
1293
1294#ifdef DEBUG
1295 if (ldebug(sched_get_priority_min))
1263{
1264 struct sched_get_priority_min_args bsd;
1265
1266#ifdef DEBUG
1267 if (ldebug(sched_get_priority_min))
1296 printf(ARGS(sched_get_priority_min, "%d"), uap->policy);
1268 printf(ARGS(sched_get_priority_min, "%d"), args->policy);
1297#endif
1298
1269#endif
1270
1299 switch (uap->policy) {
1271 switch (args->policy) {
1300 case LINUX_SCHED_OTHER:
1301 bsd.policy = SCHED_OTHER;
1302 break;
1303 case LINUX_SCHED_FIFO:
1304 bsd.policy = SCHED_FIFO;
1305 break;
1306 case LINUX_SCHED_RR:
1307 bsd.policy = SCHED_RR;

--- 10 unchanged lines hidden (view full) ---

1318
1319int
1320linux_reboot(struct proc *p, struct linux_reboot_args *args)
1321{
1322 struct reboot_args bsd_args;
1323
1324#ifdef DEBUG
1325 if (ldebug(reboot))
1272 case LINUX_SCHED_OTHER:
1273 bsd.policy = SCHED_OTHER;
1274 break;
1275 case LINUX_SCHED_FIFO:
1276 bsd.policy = SCHED_FIFO;
1277 break;
1278 case LINUX_SCHED_RR:
1279 bsd.policy = SCHED_RR;

--- 10 unchanged lines hidden (view full) ---

1290
1291int
1292linux_reboot(struct proc *p, struct linux_reboot_args *args)
1293{
1294 struct reboot_args bsd_args;
1295
1296#ifdef DEBUG
1297 if (ldebug(reboot))
1326 printf(ARGS(reboot, "0x%x"), args->opt);
1298 printf(ARGS(reboot, "0x%x"), args->cmd);
1327#endif
1299#endif
1328 if (args->opt == REBOOT_CAD_ON || args->opt == REBOOT_CAD_OFF)
1300 if (args->cmd == REBOOT_CAD_ON || args->cmd == REBOOT_CAD_OFF)
1329 return (0);
1301 return (0);
1330 bsd_args.opt = args->opt == REBOOT_HALT ? RB_HALT : 0;
1302 bsd_args.opt = (args->cmd == REBOOT_HALT) ? RB_HALT : 0;
1331 return (reboot(p, &bsd_args));
1332}
1303 return (reboot(p, &bsd_args));
1304}
1305
1306/*
1307 * The FreeBSD native getpid(2), getgid(2) and getuid(2) also modify
1308 * p->p_retval[1] when COMPAT_43 or COMPAT_SUNOS is defined. This
1309 * globbers registers that are assumed to be preserved. The following
1310 * lightweight syscalls fixes this. See also linux_getgid16() and
1311 * linux_getuid16() in linux_uid16.c.
1312 *
1313 * linux_getpid() - MP SAFE
1314 * linux_getgid() - MP SAFE
1315 * linux_getuid() - MP SAFE
1316 */
1317
1318int
1319linux_getpid(struct proc *p, struct linux_getpid_args *args)
1320{
1321 p->p_retval[0] = p->p_pid;
1322 return (0);
1323}
1324
1325int
1326linux_getgid(struct proc *p, struct linux_getgid_args *args)
1327{
1328 p->p_retval[0] = p->p_ucred->cr_rgid;
1329 return (0);
1330}
1331
1332int
1333linux_getuid(struct proc *p, struct linux_getuid_args *args)
1334{
1335 p->p_retval[0] = p->p_ucred->cr_ruid;
1336 return (0);
1337}