Annotation of src/sys/compat/linux/common/linux_oldmmap.c, Revision 1.36
1.36 ! fvdl 1: /* $NetBSD: linux_misc.c,v 1.35 1997/10/10 22:16:10 fvdl Exp $ */
1.1 fvdl 2:
3: /*
4: * Copyright (c) 1995 Frank van der Linden
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed for the NetBSD Project
18: * by Frank van der Linden
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34: /*
35: * Linux compatibility module. Try to deal with various Linux system calls.
36: */
37:
38: #include <sys/param.h>
39: #include <sys/systm.h>
40: #include <sys/namei.h>
41: #include <sys/proc.h>
1.29 mycroft 42: #include <sys/dirent.h>
1.1 fvdl 43: #include <sys/file.h>
44: #include <sys/stat.h>
45: #include <sys/filedesc.h>
46: #include <sys/ioctl.h>
47: #include <sys/kernel.h>
48: #include <sys/malloc.h>
49: #include <sys/mbuf.h>
50: #include <sys/mman.h>
51: #include <sys/mount.h>
52: #include <sys/ptrace.h>
53: #include <sys/resource.h>
54: #include <sys/resourcevar.h>
55: #include <sys/signal.h>
56: #include <sys/signalvar.h>
57: #include <sys/socket.h>
58: #include <sys/time.h>
59: #include <sys/times.h>
60: #include <sys/vnode.h>
61: #include <sys/uio.h>
62: #include <sys/wait.h>
63: #include <sys/utsname.h>
64: #include <sys/unistd.h>
65:
66: #include <sys/syscallargs.h>
67:
68: #include <vm/vm.h>
69: #include <vm/vm_param.h>
70:
71: #include <compat/linux/linux_types.h>
72: #include <compat/linux/linux_fcntl.h>
73: #include <compat/linux/linux_mmap.h>
1.11 mycroft 74: #include <compat/linux/linux_signal.h>
1.1 fvdl 75: #include <compat/linux/linux_syscallargs.h>
76: #include <compat/linux/linux_util.h>
77: #include <compat/linux/linux_dirent.h>
78:
1.26 christos 79: /* linux_misc.c */
80: static void bsd_to_linux_wstat __P((int *));
81: static void bsd_to_linux_statfs __P((struct statfs *, struct linux_statfs *));
82: int linux_select1 __P((struct proc *, register_t *, int, fd_set *, fd_set *,
83: fd_set *, struct timeval *));
84:
1.1 fvdl 85: /*
86: * The information on a terminated (or stopped) process needs
87: * to be converted in order for Linux binaries to get a valid signal
88: * number out of it.
89: */
1.25 mycroft 90: static void
1.1 fvdl 91: bsd_to_linux_wstat(status)
92: int *status;
93: {
1.21 mycroft 94:
1.1 fvdl 95: if (WIFSIGNALED(*status))
96: *status = (*status & ~0177) |
1.12 mycroft 97: bsd_to_linux_sig[WTERMSIG(*status)];
1.1 fvdl 98: else if (WIFSTOPPED(*status))
99: *status = (*status & ~0xff00) |
1.12 mycroft 100: (bsd_to_linux_sig[WSTOPSIG(*status)] << 8);
1.1 fvdl 101: }
102:
103: /*
104: * waitpid(2). Passed on to the NetBSD call, surrounded by code to
105: * reserve some space for a NetBSD-style wait status, and converting
106: * it to what Linux wants.
107: */
108: int
1.21 mycroft 109: linux_sys_waitpid(p, v, retval)
1.1 fvdl 110: struct proc *p;
1.20 thorpej 111: void *v;
112: register_t *retval;
113: {
1.21 mycroft 114: struct linux_sys_waitpid_args /* {
1.1 fvdl 115: syscallarg(int) pid;
116: syscallarg(int *) status;
117: syscallarg(int) options;
1.20 thorpej 118: } */ *uap = v;
1.21 mycroft 119: struct sys_wait4_args w4a;
1.1 fvdl 120: int error, *status, tstat;
121: caddr_t sg;
122:
1.16 fvdl 123: if (SCARG(uap, status) != NULL) {
124: sg = stackgap_init(p->p_emul);
125: status = (int *) stackgap_alloc(&sg, sizeof status);
126: } else
127: status = NULL;
1.1 fvdl 128:
129: SCARG(&w4a, pid) = SCARG(uap, pid);
130: SCARG(&w4a, status) = status;
131: SCARG(&w4a, options) = SCARG(uap, options);
132: SCARG(&w4a, rusage) = NULL;
133:
1.21 mycroft 134: if ((error = sys_wait4(p, &w4a, retval)))
1.1 fvdl 135: return error;
136:
1.18 fvdl 137: p->p_siglist &= ~sigmask(SIGCHLD);
138:
1.16 fvdl 139: if (status != NULL) {
140: if ((error = copyin(status, &tstat, sizeof tstat)))
141: return error;
142:
143: bsd_to_linux_wstat(&tstat);
144: return copyout(&tstat, SCARG(uap, status), sizeof tstat);
145: }
1.1 fvdl 146:
1.16 fvdl 147: return 0;
1.1 fvdl 148: }
149:
150: /*
151: * This is very much the same as waitpid()
152: */
153: int
1.21 mycroft 154: linux_sys_wait4(p, v, retval)
1.1 fvdl 155: struct proc *p;
1.20 thorpej 156: void *v;
157: register_t *retval;
158: {
1.21 mycroft 159: struct linux_sys_wait4_args /* {
1.1 fvdl 160: syscallarg(int) pid;
161: syscallarg(int *) status;
162: syscallarg(int) options;
163: syscallarg(struct rusage *) rusage;
1.20 thorpej 164: } */ *uap = v;
1.21 mycroft 165: struct sys_wait4_args w4a;
1.1 fvdl 166: int error, *status, tstat;
167: caddr_t sg;
168:
1.16 fvdl 169: if (SCARG(uap, status) != NULL) {
170: sg = stackgap_init(p->p_emul);
171: status = (int *) stackgap_alloc(&sg, sizeof status);
172: } else
173: status = NULL;
1.1 fvdl 174:
175: SCARG(&w4a, pid) = SCARG(uap, pid);
176: SCARG(&w4a, status) = status;
177: SCARG(&w4a, options) = SCARG(uap, options);
178: SCARG(&w4a, rusage) = SCARG(uap, rusage);
179:
1.21 mycroft 180: if ((error = sys_wait4(p, &w4a, retval)))
1.1 fvdl 181: return error;
182:
1.18 fvdl 183: p->p_siglist &= ~sigmask(SIGCHLD);
184:
1.16 fvdl 185: if (status != NULL) {
186: if ((error = copyin(status, &tstat, sizeof tstat)))
187: return error;
188:
189: bsd_to_linux_wstat(&tstat);
190: return copyout(&tstat, SCARG(uap, status), sizeof tstat);
191: }
1.1 fvdl 192:
1.16 fvdl 193: return 0;
1.1 fvdl 194: }
195:
196: /*
197: * This is the old brk(2) call. I don't think anything in the Linux
198: * world uses this anymore
199: */
200: int
1.21 mycroft 201: linux_sys_break(p, v, retval)
1.1 fvdl 202: struct proc *p;
1.20 thorpej 203: void *v;
204: register_t *retval;
205: {
1.26 christos 206: #if 0
1.21 mycroft 207: struct linux_sys_brk_args /* {
1.1 fvdl 208: syscallarg(char *) nsize;
1.20 thorpej 209: } */ *uap = v;
1.26 christos 210: #endif
1.20 thorpej 211:
1.1 fvdl 212: return ENOSYS;
213: }
214:
215: /*
216: * Linux brk(2). The check if the new address is >= the old one is
217: * done in the kernel in Linux. NetBSD does it in the library.
218: */
219: int
1.21 mycroft 220: linux_sys_brk(p, v, retval)
1.1 fvdl 221: struct proc *p;
1.20 thorpej 222: void *v;
223: register_t *retval;
224: {
1.21 mycroft 225: struct linux_sys_brk_args /* {
1.1 fvdl 226: syscallarg(char *) nsize;
1.20 thorpej 227: } */ *uap = v;
1.1 fvdl 228: char *nbrk = SCARG(uap, nsize);
1.21 mycroft 229: struct sys_obreak_args oba;
1.1 fvdl 230: struct vmspace *vm = p->p_vmspace;
1.26 christos 231: caddr_t oldbrk;
1.1 fvdl 232:
233: oldbrk = vm->vm_daddr + ctob(vm->vm_dsize);
234: /*
235: * XXX inconsistent.. Linux always returns at least the old
236: * brk value, but it will be page-aligned if this fails,
237: * and possibly not page aligned if it succeeds (the user
238: * supplied pointer is returned).
239: */
240: SCARG(&oba, nsize) = nbrk;
241:
1.21 mycroft 242: if ((caddr_t) nbrk > vm->vm_daddr && sys_obreak(p, &oba, retval) == 0)
243: retval[0] = (register_t)nbrk;
1.1 fvdl 244: else
1.21 mycroft 245: retval[0] = (register_t)oldbrk;
1.1 fvdl 246:
247: return 0;
248: }
249:
250: /*
251: * I wonder why Linux has gettimeofday() _and_ time().. Still, we
252: * need to deal with it.
253: */
254: int
1.21 mycroft 255: linux_sys_time(p, v, retval)
1.1 fvdl 256: struct proc *p;
1.20 thorpej 257: void *v;
258: register_t *retval;
259: {
1.21 mycroft 260: struct linux_sys_time_args /* {
1.1 fvdl 261: linux_time_t *t;
1.20 thorpej 262: } */ *uap = v;
1.1 fvdl 263: struct timeval atv;
264: linux_time_t tt;
265: int error;
266:
267: microtime(&atv);
268:
269: tt = atv.tv_sec;
270: if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt)))
271: return error;
272:
273: retval[0] = tt;
274: return 0;
275: }
276:
277: /*
1.2 fvdl 278: * Convert BSD statfs structure to Linux statfs structure.
279: * The Linux structure has less fields, and it also wants
280: * the length of a name in a dir entry in a field, which
281: * we fake (probably the wrong way).
282: */
283: static void
284: bsd_to_linux_statfs(bsp, lsp)
285: struct statfs *bsp;
286: struct linux_statfs *lsp;
287: {
1.21 mycroft 288:
1.2 fvdl 289: lsp->l_ftype = bsp->f_type;
290: lsp->l_fbsize = bsp->f_bsize;
291: lsp->l_fblocks = bsp->f_blocks;
292: lsp->l_fbfree = bsp->f_bfree;
293: lsp->l_fbavail = bsp->f_bavail;
294: lsp->l_ffiles = bsp->f_files;
295: lsp->l_fffree = bsp->f_ffree;
296: lsp->l_ffsid.val[0] = bsp->f_fsid.val[0];
297: lsp->l_ffsid.val[1] = bsp->f_fsid.val[1];
298: lsp->l_fnamelen = MAXNAMLEN; /* XXX */
299: }
300:
301: /*
302: * Implement the fs stat functions. Straightforward.
1.1 fvdl 303: */
304: int
1.21 mycroft 305: linux_sys_statfs(p, v, retval)
1.1 fvdl 306: struct proc *p;
1.20 thorpej 307: void *v;
308: register_t *retval;
309: {
1.21 mycroft 310: struct linux_sys_statfs_args /* {
1.1 fvdl 311: syscallarg(char *) path;
312: syscallarg(struct linux_statfs *) sp;
1.20 thorpej 313: } */ *uap = v;
1.2 fvdl 314: struct statfs btmp, *bsp;
315: struct linux_statfs ltmp;
1.21 mycroft 316: struct sys_statfs_args bsa;
1.2 fvdl 317: caddr_t sg;
318: int error;
319:
1.9 christos 320: sg = stackgap_init(p->p_emul);
1.2 fvdl 321: bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs));
322:
1.9 christos 323: LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
1.2 fvdl 324:
325: SCARG(&bsa, path) = SCARG(uap, path);
326: SCARG(&bsa, buf) = bsp;
327:
1.21 mycroft 328: if ((error = sys_statfs(p, &bsa, retval)))
1.2 fvdl 329: return error;
330:
331: if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
332: return error;
333:
334: bsd_to_linux_statfs(&btmp, <mp);
335:
336: return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
1.1 fvdl 337: }
338:
339: int
1.21 mycroft 340: linux_sys_fstatfs(p, v, retval)
1.1 fvdl 341: struct proc *p;
1.20 thorpej 342: void *v;
343: register_t *retval;
344: {
1.21 mycroft 345: struct linux_sys_fstatfs_args /* {
1.2 fvdl 346: syscallarg(int) fd;
1.1 fvdl 347: syscallarg(struct linux_statfs *) sp;
1.20 thorpej 348: } */ *uap = v;
1.2 fvdl 349: struct statfs btmp, *bsp;
350: struct linux_statfs ltmp;
1.21 mycroft 351: struct sys_fstatfs_args bsa;
1.2 fvdl 352: caddr_t sg;
353: int error;
354:
1.9 christos 355: sg = stackgap_init(p->p_emul);
1.2 fvdl 356: bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs));
357:
358: SCARG(&bsa, fd) = SCARG(uap, fd);
359: SCARG(&bsa, buf) = bsp;
360:
1.21 mycroft 361: if ((error = sys_fstatfs(p, &bsa, retval)))
1.2 fvdl 362: return error;
363:
364: if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
365: return error;
366:
367: bsd_to_linux_statfs(&btmp, <mp);
368:
369: return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
1.1 fvdl 370: }
371:
372: /*
373: * uname(). Just copy the info from the various strings stored in the
374: * kernel, and put it in the Linux utsname structure. That structure
375: * is almost the same as the NetBSD one, only it has fields 65 characters
376: * long, and an extra domainname field.
377: */
378: int
1.21 mycroft 379: linux_sys_uname(p, v, retval)
1.1 fvdl 380: struct proc *p;
1.20 thorpej 381: void *v;
382: register_t *retval;
383: {
1.21 mycroft 384: struct linux_sys_uname_args /* {
1.1 fvdl 385: syscallarg(struct linux_utsname *) up;
1.20 thorpej 386: } */ *uap = v;
1.15 mycroft 387: extern char ostype[], hostname[], osrelease[], version[], machine[],
388: domainname[];
389: struct linux_utsname luts;
1.1 fvdl 390: int len;
391: char *cp;
392:
1.15 mycroft 393: strncpy(luts.l_sysname, ostype, sizeof(luts.l_sysname));
394: strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
395: strncpy(luts.l_release, osrelease, sizeof(luts.l_release));
396: strncpy(luts.l_version, version, sizeof(luts.l_version));
397: strncpy(luts.l_machine, machine, sizeof(luts.l_machine));
398: strncpy(luts.l_domainname, domainname, sizeof(luts.l_domainname));
1.1 fvdl 399:
400: /* This part taken from the the uname() in libc */
1.15 mycroft 401: len = sizeof(luts.l_version);
402: for (cp = luts.l_version; len--; ++cp)
1.1 fvdl 403: if (*cp == '\n' || *cp == '\t')
404: if (len > 1)
405: *cp = ' ';
406: else
407: *cp = '\0';
408:
1.15 mycroft 409: return copyout(&luts, SCARG(uap, up), sizeof(luts));
410: }
411:
412: int
1.21 mycroft 413: linux_sys_olduname(p, v, retval)
1.15 mycroft 414: struct proc *p;
1.20 thorpej 415: void *v;
416: register_t *retval;
417: {
1.21 mycroft 418: struct linux_sys_uname_args /* {
1.15 mycroft 419: syscallarg(struct linux_oldutsname *) up;
1.20 thorpej 420: } */ *uap = v;
1.15 mycroft 421: extern char ostype[], hostname[], osrelease[], version[], machine[];
422: struct linux_oldutsname luts;
423: int len;
424: char *cp;
425:
426: strncpy(luts.l_sysname, ostype, sizeof(luts.l_sysname));
427: strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
428: strncpy(luts.l_release, osrelease, sizeof(luts.l_release));
429: strncpy(luts.l_version, version, sizeof(luts.l_version));
430: strncpy(luts.l_machine, machine, sizeof(luts.l_machine));
431:
432: /* This part taken from the the uname() in libc */
433: len = sizeof(luts.l_version);
434: for (cp = luts.l_version; len--; ++cp)
435: if (*cp == '\n' || *cp == '\t')
436: if (len > 1)
437: *cp = ' ';
438: else
439: *cp = '\0';
440:
441: return copyout(&luts, SCARG(uap, up), sizeof(luts));
442: }
443:
444: int
1.21 mycroft 445: linux_sys_oldolduname(p, v, retval)
1.15 mycroft 446: struct proc *p;
1.20 thorpej 447: void *v;
448: register_t *retval;
449: {
1.21 mycroft 450: struct linux_sys_uname_args /* {
1.15 mycroft 451: syscallarg(struct linux_oldoldutsname *) up;
1.20 thorpej 452: } */ *uap = v;
1.15 mycroft 453: extern char ostype[], hostname[], osrelease[], version[], machine[];
454: struct linux_oldoldutsname luts;
455: int len;
456: char *cp;
457:
458: strncpy(luts.l_sysname, ostype, sizeof(luts.l_sysname));
459: strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
460: strncpy(luts.l_release, osrelease, sizeof(luts.l_release));
461: strncpy(luts.l_version, version, sizeof(luts.l_version));
462: strncpy(luts.l_machine, machine, sizeof(luts.l_machine));
463:
464: /* This part taken from the the uname() in libc */
465: len = sizeof(luts.l_version);
466: for (cp = luts.l_version; len--; ++cp)
467: if (*cp == '\n' || *cp == '\t')
468: if (len > 1)
469: *cp = ' ';
470: else
471: *cp = '\0';
472:
473: return copyout(&luts, SCARG(uap, up), sizeof(luts));
1.1 fvdl 474: }
475:
476: /*
477: * Linux wants to pass everything to a syscall in registers. However,
478: * mmap() has 6 of them. Oops: out of register error. They just pass
479: * everything in a structure.
480: */
481: int
1.21 mycroft 482: linux_sys_mmap(p, v, retval)
1.1 fvdl 483: struct proc *p;
1.20 thorpej 484: void *v;
485: register_t *retval;
486: {
1.21 mycroft 487: struct linux_sys_mmap_args /* {
1.1 fvdl 488: syscallarg(struct linux_mmap *) lmp;
1.20 thorpej 489: } */ *uap = v;
1.1 fvdl 490: struct linux_mmap lmap;
1.21 mycroft 491: struct sys_mmap_args cma;
1.1 fvdl 492: int error, flags;
493:
494: if ((error = copyin(SCARG(uap, lmp), &lmap, sizeof lmap)))
495: return error;
496:
497: flags = 0;
498: flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_SHARED, MAP_SHARED);
499: flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_PRIVATE, MAP_PRIVATE);
500: flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_FIXED, MAP_FIXED);
501: flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_ANON, MAP_ANON);
502:
503: SCARG(&cma,addr) = lmap.lm_addr;
504: SCARG(&cma,len) = lmap.lm_len;
1.31 augustss 505: if (lmap.lm_prot & VM_PROT_WRITE) /* XXX */
506: lmap.lm_prot |= VM_PROT_READ;
1.1 fvdl 507: SCARG(&cma,prot) = lmap.lm_prot;
508: SCARG(&cma,flags) = flags;
509: SCARG(&cma,fd) = lmap.lm_fd;
510: SCARG(&cma,pad) = 0;
511: SCARG(&cma,pos) = lmap.lm_pos;
512:
1.21 mycroft 513: return sys_mmap(p, &cma, retval);
1.34 mycroft 514: }
515:
516: int
517: linux_sys_mremap(p, v, retval)
518: struct proc *p;
519: void *v;
520: register_t *retval;
521: {
522: #ifdef notyet
523: struct linux_sys_mremap_args /* {
524: syscallarg(void *) old_address;
525: syscallarg(size_t) old_size;
526: syscallarg(size_t) new_size;
527: syscallarg(u_long) flags;
528: } */ *uap = v;
529: #endif
530:
531: return ENOMEM;
1.24 fvdl 532: }
533:
534: int
535: linux_sys_msync(p, v, retval)
536: struct proc *p;
537: void *v;
538: register_t *retval;
539: {
540: struct linux_sys_msync_args /* {
541: syscallarg(caddr_t) addr;
542: syscallarg(int) len;
543: syscallarg(int) fl;
544: } */ *uap = v;
545:
1.36 ! fvdl 546: struct sys___msync13_args bma;
1.24 fvdl 547:
548: /* flags are ignored */
549: SCARG(&bma, addr) = SCARG(uap, addr);
550: SCARG(&bma, len) = SCARG(uap, len);
1.36 ! fvdl 551: SCARG(&bma, flags) = SCARG(uap, fl);
1.24 fvdl 552:
1.36 ! fvdl 553: return sys___msync13(p, &bma, retval);
1.1 fvdl 554: }
555:
556: /*
557: * This code is partly stolen from src/lib/libc/compat-43/times.c
558: * XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
559: */
560:
561: #define CLK_TCK 100
562: #define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
563:
564: int
1.21 mycroft 565: linux_sys_times(p, v, retval)
1.1 fvdl 566: struct proc *p;
1.20 thorpej 567: void *v;
568: register_t *retval;
569: {
1.21 mycroft 570: struct linux_sys_times_args /* {
1.1 fvdl 571: syscallarg(struct times *) tms;
1.20 thorpej 572: } */ *uap = v;
1.1 fvdl 573: struct timeval t;
574: struct linux_tms ltms;
575: struct rusage ru;
1.4 mycroft 576: int error, s;
1.1 fvdl 577:
578: calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
579: ltms.ltms_utime = CONVTCK(ru.ru_utime);
580: ltms.ltms_stime = CONVTCK(ru.ru_stime);
581:
582: ltms.ltms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime);
583: ltms.ltms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime);
584:
585: if ((error = copyout(<ms, SCARG(uap, tms), sizeof ltms)))
586: return error;
587:
1.4 mycroft 588: s = splclock();
589: timersub(&time, &boottime, &t);
590: splx(s);
1.1 fvdl 591:
592: retval[0] = ((linux_clock_t)(CONVTCK(t)));
593: return 0;
594: }
595:
596: /*
597: * NetBSD passes fd[0] in retval[0], and fd[1] in retval[1].
598: * Linux directly passes the pointer.
599: */
600: int
1.21 mycroft 601: linux_sys_pipe(p, v, retval)
1.1 fvdl 602: struct proc *p;
1.20 thorpej 603: void *v;
604: register_t *retval;
605: {
1.21 mycroft 606: struct linux_sys_pipe_args /* {
1.1 fvdl 607: syscallarg(int *) pfds;
1.20 thorpej 608: } */ *uap = v;
1.1 fvdl 609: int error;
610:
1.21 mycroft 611: if ((error = sys_pipe(p, 0, retval)))
1.1 fvdl 612: return error;
613:
614: /* Assumes register_t is an int */
615:
616: if ((error = copyout(retval, SCARG(uap, pfds), 2 * sizeof (int))))
617: return error;
618:
619: retval[0] = 0;
620: return 0;
621: }
622:
623: /*
1.21 mycroft 624: * Alarm. This is a libc call which uses setitimer(2) in NetBSD.
1.1 fvdl 625: * Fiddle with the timers to make it work.
626: */
627: int
1.21 mycroft 628: linux_sys_alarm(p, v, retval)
1.1 fvdl 629: struct proc *p;
1.20 thorpej 630: void *v;
631: register_t *retval;
632: {
1.21 mycroft 633: struct linux_sys_alarm_args /* {
1.1 fvdl 634: syscallarg(unsigned int) secs;
1.20 thorpej 635: } */ *uap = v;
1.26 christos 636: int s;
1.1 fvdl 637: struct itimerval *itp, it;
638:
639: itp = &p->p_realtimer;
640: s = splclock();
641: /*
642: * Clear any pending timer alarms.
643: */
644: untimeout(realitexpire, p);
645: timerclear(&itp->it_interval);
646: if (timerisset(&itp->it_value) &&
647: timercmp(&itp->it_value, &time, >))
1.3 mycroft 648: timersub(&itp->it_value, &time, &itp->it_value);
1.1 fvdl 649: /*
650: * Return how many seconds were left (rounded up)
651: */
652: retval[0] = itp->it_value.tv_sec;
653: if (itp->it_value.tv_usec)
654: retval[0]++;
655:
656: /*
657: * alarm(0) just resets the timer.
658: */
659: if (SCARG(uap, secs) == 0) {
660: timerclear(&itp->it_value);
661: splx(s);
662: return 0;
663: }
664:
665: /*
666: * Check the new alarm time for sanity, and set it.
667: */
668: timerclear(&it.it_interval);
669: it.it_value.tv_sec = SCARG(uap, secs);
670: it.it_value.tv_usec = 0;
671: if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) {
672: splx(s);
673: return (EINVAL);
674: }
675:
676: if (timerisset(&it.it_value)) {
1.3 mycroft 677: timeradd(&it.it_value, &time, &it.it_value);
1.1 fvdl 678: timeout(realitexpire, p, hzto(&it.it_value));
679: }
680: p->p_realtimer = it;
681: splx(s);
682:
683: return 0;
684: }
685:
686: /*
687: * utime(). Do conversion to things that utimes() understands,
688: * and pass it on.
689: */
690: int
1.21 mycroft 691: linux_sys_utime(p, v, retval)
1.1 fvdl 692: struct proc *p;
1.20 thorpej 693: void *v;
694: register_t *retval;
695: {
1.21 mycroft 696: struct linux_sys_utime_args /* {
1.1 fvdl 697: syscallarg(char *) path;
698: syscallarg(struct linux_utimbuf *)times;
1.20 thorpej 699: } */ *uap = v;
1.1 fvdl 700: caddr_t sg;
701: int error;
1.21 mycroft 702: struct sys_utimes_args ua;
1.1 fvdl 703: struct timeval tv[2], *tvp;
704: struct linux_utimbuf lut;
705:
1.9 christos 706: sg = stackgap_init(p->p_emul);
707: LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
1.1 fvdl 708:
709: SCARG(&ua, path) = SCARG(uap, path);
710:
711: if (SCARG(uap, times) != NULL) {
712: if ((error = copyin(SCARG(uap, times), &lut, sizeof lut)))
713: return error;
714: tv[0].tv_usec = tv[1].tv_usec = 0;
715: tv[0].tv_sec = lut.l_actime;
716: tv[1].tv_sec = lut.l_modtime;
1.9 christos 717: tvp = (struct timeval *) stackgap_alloc(&sg, sizeof(tv));
1.1 fvdl 718: if ((error = copyout(tv, tvp, sizeof tv)))
719: return error;
720: SCARG(&ua, tptr) = tvp;
721: }
722: else
723: SCARG(&ua, tptr) = NULL;
724:
1.21 mycroft 725: return sys_utimes(p, uap, retval);
1.1 fvdl 726: }
727:
728: /*
1.17 fvdl 729: * The old Linux readdir was only able to read one entry at a time,
730: * even though it had a 'count' argument. In fact, the emulation
731: * of the old call was better than the original, because it did handle
732: * the count arg properly. Don't bother with it anymore now, and use
733: * it to distinguish between old and new. The difference is that the
734: * newer one actually does multiple entries, and the reclen field
735: * really is the reclen, not the namelength.
736: */
737: int
1.21 mycroft 738: linux_sys_readdir(p, v, retval)
1.17 fvdl 739: struct proc *p;
1.20 thorpej 740: void *v;
741: register_t *retval;
742: {
1.21 mycroft 743: struct linux_sys_readdir_args /* {
1.17 fvdl 744: syscallarg(int) fd;
745: syscallarg(struct linux_dirent *) dent;
746: syscallarg(unsigned int) count;
1.20 thorpej 747: } */ *uap = v;
748:
1.17 fvdl 749: SCARG(uap, count) = 1;
1.21 mycroft 750: return linux_sys_getdents(p, uap, retval);
1.17 fvdl 751: }
752:
753: /*
1.1 fvdl 754: * Linux 'readdir' call. This code is mostly taken from the
755: * SunOS getdents call (see compat/sunos/sunos_misc.c), though
756: * an attempt has been made to keep it a little cleaner (failing
757: * miserably, because of the cruft needed if count 1 is passed).
758: *
1.17 fvdl 759: * The d_off field should contain the offset of the next valid entry,
760: * but in Linux it has the offset of the entry itself. We emulate
761: * that bug here.
762: *
1.1 fvdl 763: * Read in BSD-style entries, convert them, and copy them out.
764: *
765: * Note that this doesn't handle union-mounted filesystems.
766: */
767: int
1.21 mycroft 768: linux_sys_getdents(p, v, retval)
1.1 fvdl 769: struct proc *p;
1.20 thorpej 770: void *v;
771: register_t *retval;
772: {
1.21 mycroft 773: struct linux_sys_readdir_args /* {
1.1 fvdl 774: syscallarg(int) fd;
1.21 mycroft 775: syscallarg(caddr_t) dent;
1.1 fvdl 776: syscallarg(unsigned int) count;
1.20 thorpej 777: } */ *uap = v;
1.1 fvdl 778: register struct dirent *bdp;
779: struct vnode *vp;
1.26 christos 780: caddr_t inp, buf; /* BSD-format */
781: int len, reclen; /* BSD-format */
782: caddr_t outp; /* Linux-format */
783: int resid, linux_reclen = 0; /* Linux-format */
1.1 fvdl 784: struct file *fp;
785: struct uio auio;
786: struct iovec aiov;
787: struct linux_dirent idb;
788: off_t off; /* true file offset */
1.17 fvdl 789: int buflen, error, eofflag, nbytes, oldcall;
1.1 fvdl 790: struct vattr va;
1.33 fvdl 791: off_t *cookiebuf, *cookie;
1.22 mycroft 792: int ncookies;
1.1 fvdl 793:
794: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
795: return (error);
796:
797: if ((fp->f_flag & FREAD) == 0)
798: return (EBADF);
799:
1.5 mycroft 800: vp = (struct vnode *)fp->f_data;
1.1 fvdl 801:
802: if (vp->v_type != VDIR) /* XXX vnode readdir op should do this */
803: return (EINVAL);
804:
805: if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
806: return error;
807:
808: nbytes = SCARG(uap, count);
1.17 fvdl 809: if (nbytes == 1) { /* emulating old, broken behaviour */
1.1 fvdl 810: nbytes = sizeof (struct linux_dirent);
1.5 mycroft 811: buflen = max(va.va_blocksize, nbytes);
1.17 fvdl 812: oldcall = 1;
1.5 mycroft 813: } else {
814: buflen = min(MAXBSIZE, nbytes);
1.33 fvdl 815: if (buflen < va.va_blocksize)
816: buflen = va.va_blocksize;
1.17 fvdl 817: oldcall = 0;
1.1 fvdl 818: }
819: buf = malloc(buflen, M_TEMP, M_WAITOK);
1.22 mycroft 820: ncookies = buflen / 16;
821: cookiebuf = malloc(ncookies * sizeof(*cookiebuf), M_TEMP, M_WAITOK);
1.33 fvdl 822:
1.1 fvdl 823: VOP_LOCK(vp);
824: off = fp->f_offset;
825: again:
826: aiov.iov_base = buf;
827: aiov.iov_len = buflen;
828: auio.uio_iov = &aiov;
829: auio.uio_iovcnt = 1;
830: auio.uio_rw = UIO_READ;
831: auio.uio_segflg = UIO_SYSSPACE;
832: auio.uio_procp = p;
833: auio.uio_resid = buflen;
834: auio.uio_offset = off;
835: /*
836: * First we read into the malloc'ed buffer, then
837: * we massage it into user space, one record at a time.
838: */
1.22 mycroft 839: error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, cookiebuf,
840: ncookies);
1.1 fvdl 841: if (error)
842: goto out;
843:
844: inp = buf;
1.21 mycroft 845: outp = SCARG(uap, dent);
1.1 fvdl 846: resid = nbytes;
1.35 fvdl 847: if ((len = buflen - auio.uio_resid) == 0)
1.1 fvdl 848: goto eof;
849:
1.22 mycroft 850: for (cookie = cookiebuf; len > 0; len -= reclen) {
1.5 mycroft 851: bdp = (struct dirent *)inp;
852: reclen = bdp->d_reclen;
1.1 fvdl 853: if (reclen & 3)
854: panic("linux_readdir");
855: if (bdp->d_fileno == 0) {
856: inp += reclen; /* it is a hole; squish it out */
1.22 mycroft 857: off = *cookie++;
1.1 fvdl 858: continue;
859: }
1.21 mycroft 860: linux_reclen = LINUX_RECLEN(&idb, bdp->d_namlen);
861: if (reclen > len || resid < linux_reclen) {
1.1 fvdl 862: /* entry too big for buffer, so just stop */
863: outp++;
864: break;
865: }
866: /*
867: * Massage in place to make a Linux-shaped dirent (otherwise
868: * we have to worry about touching user memory outside of
869: * the copyout() call).
870: */
1.22 mycroft 871: idb.d_ino = (linux_ino_t)bdp->d_fileno;
1.17 fvdl 872: /*
1.21 mycroft 873: * The old readdir() call misuses the offset and reclen fields.
1.17 fvdl 874: */
1.22 mycroft 875: if (oldcall) {
876: idb.d_off = (linux_off_t)linux_reclen;
877: idb.d_reclen = (u_short)bdp->d_namlen;
878: } else {
1.33 fvdl 879: if (sizeof (linux_off_t) < 4 && (off >> 32) != 0) {
880: compat_offseterr(vp, "linux_getdents");
881: error = EINVAL;
882: goto out;
883: }
1.22 mycroft 884: idb.d_off = (linux_off_t)off;
885: idb.d_reclen = (u_short)linux_reclen;
886: }
1.5 mycroft 887: strcpy(idb.d_name, bdp->d_name);
1.21 mycroft 888: if ((error = copyout((caddr_t)&idb, outp, linux_reclen)))
1.1 fvdl 889: goto out;
890: /* advance past this real entry */
891: inp += reclen;
1.22 mycroft 892: off = *cookie++; /* each entry points to itself */
1.1 fvdl 893: /* advance output past Linux-shaped entry */
1.21 mycroft 894: outp += linux_reclen;
895: resid -= linux_reclen;
1.17 fvdl 896: if (oldcall)
1.1 fvdl 897: break;
898: }
899:
900: /* if we squished out the whole block, try again */
1.21 mycroft 901: if (outp == SCARG(uap, dent))
1.1 fvdl 902: goto again;
903: fp->f_offset = off; /* update the vnode offset */
904:
1.17 fvdl 905: if (oldcall)
1.21 mycroft 906: nbytes = resid + linux_reclen;
1.1 fvdl 907:
908: eof:
909: *retval = nbytes - resid;
910: out:
911: VOP_UNLOCK(vp);
1.22 mycroft 912: free(cookiebuf, M_TEMP);
1.1 fvdl 913: free(buf, M_TEMP);
914: return error;
915: }
916:
917: /*
1.17 fvdl 918: * Not sure why the arguments to this older version of select() were put
919: * into a structure, because there are 5, and that can all be handled
920: * in registers on the i386 like Linux wants to.
921: */
922: int
1.21 mycroft 923: linux_sys_oldselect(p, v, retval)
1.17 fvdl 924: struct proc *p;
1.20 thorpej 925: void *v;
926: register_t *retval;
927: {
1.21 mycroft 928: struct linux_sys_oldselect_args /* {
1.17 fvdl 929: syscallarg(struct linux_select *) lsp;
1.20 thorpej 930: } */ *uap = v;
1.17 fvdl 931: struct linux_select ls;
932: int error;
933:
934: if ((error = copyin(SCARG(uap, lsp), &ls, sizeof(ls))))
935: return error;
936:
937: return linux_select1(p, retval, ls.nfds, ls.readfds, ls.writefds,
938: ls.exceptfds, ls.timeout);
939: }
940:
941: /*
942: * Even when just using registers to pass arguments to syscalls you can
943: * have 5 of them on the i386. So this newer version of select() does
944: * this.
1.1 fvdl 945: */
946: int
1.21 mycroft 947: linux_sys_select(p, v, retval)
1.1 fvdl 948: struct proc *p;
1.20 thorpej 949: void *v;
950: register_t *retval;
951: {
1.21 mycroft 952: struct linux_sys_select_args /* {
1.17 fvdl 953: syscallarg(int) nfds;
954: syscallarg(fd_set *) readfds;
955: syscallarg(fd_set *) writefds;
956: syscallarg(fd_set *) exceptfds;
957: syscallarg(struct timeval *) timeout;
1.20 thorpej 958: } */ *uap = v;
959:
1.17 fvdl 960: return linux_select1(p, retval, SCARG(uap, nfds), SCARG(uap, readfds),
961: SCARG(uap, writefds), SCARG(uap, exceptfds), SCARG(uap, timeout));
962: }
963:
964: /*
965: * Common code for the old and new versions of select(). A couple of
966: * things are important:
967: * 1) return the amount of time left in the 'timeout' parameter
968: * 2) select never returns ERESTART on Linux, always return EINTR
969: */
970: int
971: linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout)
972: struct proc *p;
973: register_t *retval;
974: int nfds;
975: fd_set *readfds, *writefds, *exceptfds;
976: struct timeval *timeout;
977: {
1.21 mycroft 978: struct sys_select_args bsa;
1.13 mycroft 979: struct timeval tv0, tv1, utv, *tvp;
980: caddr_t sg;
1.1 fvdl 981: int error;
982:
1.17 fvdl 983: SCARG(&bsa, nd) = nfds;
984: SCARG(&bsa, in) = readfds;
985: SCARG(&bsa, ou) = writefds;
986: SCARG(&bsa, ex) = exceptfds;
987: SCARG(&bsa, tv) = timeout;
1.1 fvdl 988:
1.7 fvdl 989: /*
990: * Store current time for computation of the amount of
991: * time left.
992: */
1.17 fvdl 993: if (timeout) {
994: if ((error = copyin(timeout, &utv, sizeof(utv))))
1.13 mycroft 995: return error;
996: if (itimerfix(&utv)) {
997: /*
998: * The timeval was invalid. Convert it to something
999: * valid that will act as it does under Linux.
1000: */
1001: sg = stackgap_init(p->p_emul);
1002: tvp = stackgap_alloc(&sg, sizeof(utv));
1003: utv.tv_sec += utv.tv_usec / 1000000;
1004: utv.tv_usec %= 1000000;
1005: if (utv.tv_usec < 0) {
1006: utv.tv_sec -= 1;
1007: utv.tv_usec += 1000000;
1008: }
1009: if (utv.tv_sec < 0)
1010: timerclear(&utv);
1011: if ((error = copyout(&utv, tvp, sizeof(utv))))
1012: return error;
1013: SCARG(&bsa, tv) = tvp;
1014: }
1.7 fvdl 1015: microtime(&tv0);
1.13 mycroft 1016: }
1.7 fvdl 1017:
1.21 mycroft 1018: error = sys_select(p, &bsa, retval);
1.10 mycroft 1019: if (error) {
1020: /*
1021: * See fs/select.c in the Linux kernel. Without this,
1022: * Maelstrom doesn't work.
1023: */
1024: if (error == ERESTART)
1025: error = EINTR;
1.7 fvdl 1026: return error;
1.10 mycroft 1027: }
1.7 fvdl 1028:
1.17 fvdl 1029: if (timeout) {
1.14 mycroft 1030: if (*retval) {
1.7 fvdl 1031: /*
1.13 mycroft 1032: * Compute how much time was left of the timeout,
1.7 fvdl 1033: * by subtracting the current time and the time
1034: * before we started the call, and subtracting
1035: * that result from the user-supplied value.
1036: */
1037: microtime(&tv1);
1038: timersub(&tv1, &tv0, &tv1);
1039: timersub(&utv, &tv1, &utv);
1.14 mycroft 1040: if (utv.tv_sec < 0)
1041: timerclear(&utv);
1042: } else
1043: timerclear(&utv);
1.17 fvdl 1044: if ((error = copyout(&utv, timeout, sizeof(utv))))
1.7 fvdl 1045: return error;
1046: }
1.13 mycroft 1047:
1.7 fvdl 1048: return 0;
1.1 fvdl 1049: }
1050:
1051: /*
1052: * Get the process group of a certain process. Look it up
1053: * and return the value.
1054: */
1055: int
1.21 mycroft 1056: linux_sys_getpgid(p, v, retval)
1.1 fvdl 1057: struct proc *p;
1.20 thorpej 1058: void *v;
1059: register_t *retval;
1060: {
1.21 mycroft 1061: struct linux_sys_getpgid_args /* {
1.1 fvdl 1062: syscallarg(int) pid;
1.20 thorpej 1063: } */ *uap = v;
1.1 fvdl 1064: struct proc *targp;
1065:
1.26 christos 1066: if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) {
1.1 fvdl 1067: if ((targp = pfind(SCARG(uap, pid))) == 0)
1068: return ESRCH;
1.26 christos 1069: }
1.1 fvdl 1070: else
1071: targp = p;
1072:
1073: retval[0] = targp->p_pgid;
1.6 fvdl 1074: return 0;
1075: }
1076:
1077: /*
1078: * Set the 'personality' (emulation mode) for the current process. Only
1079: * accept the Linux personality here (0). This call is needed because
1080: * the Linux ELF crt0 issues it in an ugly kludge to make sure that
1081: * ELF binaries run in Linux mode, not SVR4 mode.
1082: */
1083: int
1.21 mycroft 1084: linux_sys_personality(p, v, retval)
1.6 fvdl 1085: struct proc *p;
1.20 thorpej 1086: void *v;
1087: register_t *retval;
1088: {
1.21 mycroft 1089: struct linux_sys_personality_args /* {
1.6 fvdl 1090: syscallarg(int) per;
1.20 thorpej 1091: } */ *uap = v;
1092:
1.6 fvdl 1093: if (SCARG(uap, per) != 0)
1094: return EINVAL;
1095: retval[0] = 0;
1.1 fvdl 1096: return 0;
1.18 fvdl 1097: }
1098:
1099: /*
1100: * The calls are here because of type conversions.
1101: */
1102: int
1.21 mycroft 1103: linux_sys_setreuid(p, v, retval)
1.18 fvdl 1104: struct proc *p;
1.20 thorpej 1105: void *v;
1106: register_t *retval;
1107: {
1.21 mycroft 1108: struct linux_sys_setreuid_args /* {
1.18 fvdl 1109: syscallarg(int) ruid;
1110: syscallarg(int) euid;
1.20 thorpej 1111: } */ *uap = v;
1.28 mycroft 1112: struct sys_setreuid_args bsa;
1.18 fvdl 1113:
1114: SCARG(&bsa, ruid) = ((linux_uid_t)SCARG(uap, ruid) == (linux_uid_t)-1) ?
1115: (uid_t)-1 : SCARG(uap, ruid);
1116: SCARG(&bsa, euid) = ((linux_uid_t)SCARG(uap, euid) == (linux_uid_t)-1) ?
1117: (uid_t)-1 : SCARG(uap, euid);
1118:
1.28 mycroft 1119: return sys_setreuid(p, &bsa, retval);
1.18 fvdl 1120: }
1121:
1122: int
1.21 mycroft 1123: linux_sys_setregid(p, v, retval)
1.18 fvdl 1124: struct proc *p;
1.20 thorpej 1125: void *v;
1126: register_t *retval;
1127: {
1.21 mycroft 1128: struct linux_sys_setregid_args /* {
1.18 fvdl 1129: syscallarg(int) rgid;
1130: syscallarg(int) egid;
1.20 thorpej 1131: } */ *uap = v;
1.28 mycroft 1132: struct sys_setregid_args bsa;
1.18 fvdl 1133:
1134: SCARG(&bsa, rgid) = ((linux_gid_t)SCARG(uap, rgid) == (linux_gid_t)-1) ?
1135: (uid_t)-1 : SCARG(uap, rgid);
1136: SCARG(&bsa, egid) = ((linux_gid_t)SCARG(uap, egid) == (linux_gid_t)-1) ?
1137: (uid_t)-1 : SCARG(uap, egid);
1138:
1.28 mycroft 1139: return sys_setregid(p, &bsa, retval);
1.27 fvdl 1140: }
1141:
1142: int
1143: linux_sys_getsid(p, v, retval)
1144: struct proc *p;
1145: void *v;
1146: register_t *retval;
1147: {
1148: struct linux_sys_getsid_args /* {
1149: syscallarg(int) pid;
1150: } */ *uap = v;
1151: struct proc *p1;
1152: pid_t pid;
1153:
1154: pid = (pid_t)SCARG(uap, pid);
1155:
1156: if (pid == 0) {
1157: retval[0] = (int)p->p_session; /* XXX Oh well */
1158: return 0;
1159: }
1160:
1161: p1 = pfind((int)pid);
1162: if (p1 == NULL)
1163: return ESRCH;
1164:
1165: retval[0] = (int)p1->p_session;
1166: return 0;
1167: }
1168:
1169: int
1170: linux_sys___sysctl(p, v, retval)
1171: struct proc *p;
1172: void *v;
1173: register_t *retval;
1174: {
1175: struct linux_sys___sysctl_args /* {
1176: syscallarg(struct linux___sysctl *) lsp;
1177: } */ *uap = v;
1178: struct linux___sysctl ls;
1179: struct sys___sysctl_args bsa;
1180: int error;
1181:
1182: if ((error = copyin(SCARG(uap, lsp), &ls, sizeof ls)))
1183: return error;
1184: SCARG(&bsa, name) = ls.name;
1185: SCARG(&bsa, namelen) = ls.namelen;
1186: SCARG(&bsa, old) = ls.old;
1187: SCARG(&bsa, oldlenp) = ls.oldlenp;
1188: SCARG(&bsa, new) = ls.new;
1189: SCARG(&bsa, newlen) = ls.newlen;
1190:
1191: return sys___sysctl(p, &bsa, retval);
1.30 augustss 1192: }
1193:
1194: int
1195: linux_sys_nice(p, v, retval)
1196: struct proc *p;
1197: void *v;
1198: register_t *retval;
1199: {
1200: struct linux_sys_nice_args /* {
1201: syscallarg(int) incr;
1202: } */ *uap = v;
1203: struct sys_setpriority_args bsa;
1204:
1205: SCARG(&bsa, which) = PRIO_PROCESS;
1206: SCARG(&bsa, who) = 0;
1207: SCARG(&bsa, prio) = SCARG(uap, incr);
1208: return sys_setpriority(p, &bsa, retval);
1.1 fvdl 1209: }
CVSweb <webmaster@jp.NetBSD.org>