[BACK]Return to linux_oldmmap.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / linux / common

Annotation of src/sys/compat/linux/common/linux_oldmmap.c, Revision 1.41

1.41    ! mycroft     1: /*     $NetBSD: linux_misc.c,v 1.40 1998/03/03 13:44:48 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, &ltmp);
                    335:
                    336:        return copyout((caddr_t) &ltmp, (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, &ltmp);
                    368:
                    369:        return copyout((caddr_t) &ltmp, (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(&ltms, 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.41    ! mycroft   725:        return sys_utimes(p, &ua, 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.40      fvdl      791:        off_t *cookiebuf = NULL, *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 ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
                    803:                return error;
                    804:
                    805:        nbytes = SCARG(uap, count);
1.17      fvdl      806:        if (nbytes == 1) {      /* emulating old, broken behaviour */
1.1       fvdl      807:                nbytes = sizeof (struct linux_dirent);
1.5       mycroft   808:                buflen = max(va.va_blocksize, nbytes);
1.17      fvdl      809:                oldcall = 1;
1.5       mycroft   810:        } else {
                    811:                buflen = min(MAXBSIZE, nbytes);
1.33      fvdl      812:                if (buflen < va.va_blocksize)
                    813:                        buflen = va.va_blocksize;
1.17      fvdl      814:                oldcall = 0;
1.1       fvdl      815:        }
                    816:        buf = malloc(buflen, M_TEMP, M_WAITOK);
1.33      fvdl      817:
1.39      fvdl      818:        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.1       fvdl      819:        off = fp->f_offset;
                    820: again:
                    821:        aiov.iov_base = buf;
                    822:        aiov.iov_len = buflen;
                    823:        auio.uio_iov = &aiov;
                    824:        auio.uio_iovcnt = 1;
                    825:        auio.uio_rw = UIO_READ;
                    826:        auio.uio_segflg = UIO_SYSSPACE;
                    827:        auio.uio_procp = p;
                    828:        auio.uio_resid = buflen;
                    829:        auio.uio_offset = off;
                    830:        /*
                    831:          * First we read into the malloc'ed buffer, then
                    832:          * we massage it into user space, one record at a time.
                    833:          */
1.39      fvdl      834:        error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
                    835:            &ncookies);
1.1       fvdl      836:        if (error)
                    837:                goto out;
                    838:
                    839:        inp = buf;
1.21      mycroft   840:        outp = SCARG(uap, dent);
1.1       fvdl      841:        resid = nbytes;
1.35      fvdl      842:        if ((len = buflen - auio.uio_resid) == 0)
1.1       fvdl      843:                goto eof;
                    844:
1.22      mycroft   845:        for (cookie = cookiebuf; len > 0; len -= reclen) {
1.5       mycroft   846:                bdp = (struct dirent *)inp;
                    847:                reclen = bdp->d_reclen;
1.1       fvdl      848:                if (reclen & 3)
                    849:                        panic("linux_readdir");
                    850:                if (bdp->d_fileno == 0) {
                    851:                        inp += reclen;  /* it is a hole; squish it out */
1.22      mycroft   852:                        off = *cookie++;
1.1       fvdl      853:                        continue;
                    854:                }
1.21      mycroft   855:                linux_reclen = LINUX_RECLEN(&idb, bdp->d_namlen);
                    856:                if (reclen > len || resid < linux_reclen) {
1.1       fvdl      857:                        /* entry too big for buffer, so just stop */
                    858:                        outp++;
                    859:                        break;
                    860:                }
                    861:                /*
                    862:                 * Massage in place to make a Linux-shaped dirent (otherwise
                    863:                 * we have to worry about touching user memory outside of
                    864:                 * the copyout() call).
                    865:                 */
1.22      mycroft   866:                idb.d_ino = (linux_ino_t)bdp->d_fileno;
1.17      fvdl      867:                /*
1.21      mycroft   868:                 * The old readdir() call misuses the offset and reclen fields.
1.17      fvdl      869:                 */
1.22      mycroft   870:                if (oldcall) {
                    871:                        idb.d_off = (linux_off_t)linux_reclen;
                    872:                        idb.d_reclen = (u_short)bdp->d_namlen;
                    873:                } else {
1.33      fvdl      874:                        if (sizeof (linux_off_t) < 4 && (off >> 32) != 0) {
                    875:                                compat_offseterr(vp, "linux_getdents");
                    876:                                error = EINVAL;
                    877:                                goto out;
                    878:                        }
1.22      mycroft   879:                        idb.d_off = (linux_off_t)off;
                    880:                        idb.d_reclen = (u_short)linux_reclen;
                    881:                }
1.5       mycroft   882:                strcpy(idb.d_name, bdp->d_name);
1.21      mycroft   883:                if ((error = copyout((caddr_t)&idb, outp, linux_reclen)))
1.1       fvdl      884:                        goto out;
                    885:                /* advance past this real entry */
                    886:                inp += reclen;
1.22      mycroft   887:                off = *cookie++;        /* each entry points to itself */
1.1       fvdl      888:                /* advance output past Linux-shaped entry */
1.21      mycroft   889:                outp += linux_reclen;
                    890:                resid -= linux_reclen;
1.17      fvdl      891:                if (oldcall)
1.1       fvdl      892:                        break;
                    893:        }
                    894:
                    895:        /* if we squished out the whole block, try again */
1.21      mycroft   896:        if (outp == SCARG(uap, dent))
1.1       fvdl      897:                goto again;
                    898:        fp->f_offset = off;     /* update the vnode offset */
                    899:
1.17      fvdl      900:        if (oldcall)
1.21      mycroft   901:                nbytes = resid + linux_reclen;
1.1       fvdl      902:
                    903: eof:
                    904:        *retval = nbytes - resid;
                    905: out:
1.39      fvdl      906:        VOP_UNLOCK(vp, 0);
1.40      fvdl      907:        if (cookiebuf)
                    908:                free(cookiebuf, M_TEMP);
1.1       fvdl      909:        free(buf, M_TEMP);
                    910:        return error;
                    911: }
                    912:
                    913: /*
1.17      fvdl      914:  * Not sure why the arguments to this older version of select() were put
                    915:  * into a structure, because there are 5, and that can all be handled
                    916:  * in registers on the i386 like Linux wants to.
                    917:  */
                    918: int
1.21      mycroft   919: linux_sys_oldselect(p, v, retval)
1.17      fvdl      920:        struct proc *p;
1.20      thorpej   921:        void *v;
                    922:        register_t *retval;
                    923: {
1.21      mycroft   924:        struct linux_sys_oldselect_args /* {
1.17      fvdl      925:                syscallarg(struct linux_select *) lsp;
1.20      thorpej   926:        } */ *uap = v;
1.17      fvdl      927:        struct linux_select ls;
                    928:        int error;
                    929:
                    930:        if ((error = copyin(SCARG(uap, lsp), &ls, sizeof(ls))))
                    931:                return error;
                    932:
                    933:        return linux_select1(p, retval, ls.nfds, ls.readfds, ls.writefds,
                    934:            ls.exceptfds, ls.timeout);
                    935: }
                    936:
                    937: /*
                    938:  * Even when just using registers to pass arguments to syscalls you can
                    939:  * have 5 of them on the i386. So this newer version of select() does
                    940:  * this.
1.1       fvdl      941:  */
                    942: int
1.21      mycroft   943: linux_sys_select(p, v, retval)
1.1       fvdl      944:        struct proc *p;
1.20      thorpej   945:        void *v;
                    946:        register_t *retval;
                    947: {
1.21      mycroft   948:        struct linux_sys_select_args /* {
1.17      fvdl      949:                syscallarg(int) nfds;
                    950:                syscallarg(fd_set *) readfds;
                    951:                syscallarg(fd_set *) writefds;
                    952:                syscallarg(fd_set *) exceptfds;
                    953:                syscallarg(struct timeval *) timeout;
1.20      thorpej   954:        } */ *uap = v;
                    955:
1.17      fvdl      956:        return linux_select1(p, retval, SCARG(uap, nfds), SCARG(uap, readfds),
                    957:            SCARG(uap, writefds), SCARG(uap, exceptfds), SCARG(uap, timeout));
                    958: }
                    959:
                    960: /*
                    961:  * Common code for the old and new versions of select(). A couple of
                    962:  * things are important:
                    963:  * 1) return the amount of time left in the 'timeout' parameter
                    964:  * 2) select never returns ERESTART on Linux, always return EINTR
                    965:  */
                    966: int
                    967: linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout)
                    968:        struct proc *p;
                    969:        register_t *retval;
                    970:        int nfds;
                    971:        fd_set *readfds, *writefds, *exceptfds;
                    972:        struct timeval *timeout;
                    973: {
1.21      mycroft   974:        struct sys_select_args bsa;
1.13      mycroft   975:        struct timeval tv0, tv1, utv, *tvp;
                    976:        caddr_t sg;
1.1       fvdl      977:        int error;
                    978:
1.17      fvdl      979:        SCARG(&bsa, nd) = nfds;
                    980:        SCARG(&bsa, in) = readfds;
                    981:        SCARG(&bsa, ou) = writefds;
                    982:        SCARG(&bsa, ex) = exceptfds;
                    983:        SCARG(&bsa, tv) = timeout;
1.1       fvdl      984:
1.7       fvdl      985:        /*
                    986:         * Store current time for computation of the amount of
                    987:         * time left.
                    988:         */
1.17      fvdl      989:        if (timeout) {
                    990:                if ((error = copyin(timeout, &utv, sizeof(utv))))
1.13      mycroft   991:                        return error;
                    992:                if (itimerfix(&utv)) {
                    993:                        /*
                    994:                         * The timeval was invalid.  Convert it to something
                    995:                         * valid that will act as it does under Linux.
                    996:                         */
                    997:                        sg = stackgap_init(p->p_emul);
                    998:                        tvp = stackgap_alloc(&sg, sizeof(utv));
                    999:                        utv.tv_sec += utv.tv_usec / 1000000;
                   1000:                        utv.tv_usec %= 1000000;
                   1001:                        if (utv.tv_usec < 0) {
                   1002:                                utv.tv_sec -= 1;
                   1003:                                utv.tv_usec += 1000000;
                   1004:                        }
                   1005:                        if (utv.tv_sec < 0)
                   1006:                                timerclear(&utv);
                   1007:                        if ((error = copyout(&utv, tvp, sizeof(utv))))
                   1008:                                return error;
                   1009:                        SCARG(&bsa, tv) = tvp;
                   1010:                }
1.7       fvdl     1011:                microtime(&tv0);
1.13      mycroft  1012:        }
1.7       fvdl     1013:
1.21      mycroft  1014:        error = sys_select(p, &bsa, retval);
1.10      mycroft  1015:        if (error) {
                   1016:                /*
                   1017:                 * See fs/select.c in the Linux kernel.  Without this,
                   1018:                 * Maelstrom doesn't work.
                   1019:                 */
                   1020:                if (error == ERESTART)
                   1021:                        error = EINTR;
1.7       fvdl     1022:                return error;
1.10      mycroft  1023:        }
1.7       fvdl     1024:
1.17      fvdl     1025:        if (timeout) {
1.14      mycroft  1026:                if (*retval) {
1.7       fvdl     1027:                        /*
1.13      mycroft  1028:                         * Compute how much time was left of the timeout,
1.7       fvdl     1029:                         * by subtracting the current time and the time
                   1030:                         * before we started the call, and subtracting
                   1031:                         * that result from the user-supplied value.
                   1032:                         */
                   1033:                        microtime(&tv1);
                   1034:                        timersub(&tv1, &tv0, &tv1);
                   1035:                        timersub(&utv, &tv1, &utv);
1.14      mycroft  1036:                        if (utv.tv_sec < 0)
                   1037:                                timerclear(&utv);
                   1038:                } else
                   1039:                        timerclear(&utv);
1.17      fvdl     1040:                if ((error = copyout(&utv, timeout, sizeof(utv))))
1.7       fvdl     1041:                        return error;
                   1042:        }
1.13      mycroft  1043:
1.7       fvdl     1044:        return 0;
1.1       fvdl     1045: }
                   1046:
                   1047: /*
                   1048:  * Get the process group of a certain process. Look it up
                   1049:  * and return the value.
                   1050:  */
                   1051: int
1.21      mycroft  1052: linux_sys_getpgid(p, v, retval)
1.1       fvdl     1053:        struct proc *p;
1.20      thorpej  1054:        void *v;
                   1055:        register_t *retval;
                   1056: {
1.21      mycroft  1057:        struct linux_sys_getpgid_args /* {
1.1       fvdl     1058:                syscallarg(int) pid;
1.20      thorpej  1059:        } */ *uap = v;
1.1       fvdl     1060:        struct proc *targp;
                   1061:
1.26      christos 1062:        if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) {
1.1       fvdl     1063:                if ((targp = pfind(SCARG(uap, pid))) == 0)
                   1064:                        return ESRCH;
1.26      christos 1065:        }
1.1       fvdl     1066:        else
                   1067:                targp = p;
                   1068:
                   1069:        retval[0] = targp->p_pgid;
1.6       fvdl     1070:        return 0;
                   1071: }
                   1072:
                   1073: /*
                   1074:  * Set the 'personality' (emulation mode) for the current process. Only
                   1075:  * accept the Linux personality here (0). This call is needed because
                   1076:  * the Linux ELF crt0 issues it in an ugly kludge to make sure that
                   1077:  * ELF binaries run in Linux mode, not SVR4 mode.
                   1078:  */
                   1079: int
1.21      mycroft  1080: linux_sys_personality(p, v, retval)
1.6       fvdl     1081:        struct proc *p;
1.20      thorpej  1082:        void *v;
                   1083:        register_t *retval;
                   1084: {
1.21      mycroft  1085:        struct linux_sys_personality_args /* {
1.6       fvdl     1086:                syscallarg(int) per;
1.20      thorpej  1087:        } */ *uap = v;
                   1088:
1.6       fvdl     1089:        if (SCARG(uap, per) != 0)
                   1090:                return EINVAL;
                   1091:        retval[0] = 0;
1.1       fvdl     1092:        return 0;
1.18      fvdl     1093: }
                   1094:
                   1095: /*
                   1096:  * The calls are here because of type conversions.
                   1097:  */
                   1098: int
1.21      mycroft  1099: linux_sys_setreuid(p, v, retval)
1.18      fvdl     1100:        struct proc *p;
1.20      thorpej  1101:        void *v;
                   1102:        register_t *retval;
                   1103: {
1.21      mycroft  1104:        struct linux_sys_setreuid_args /* {
1.18      fvdl     1105:                syscallarg(int) ruid;
                   1106:                syscallarg(int) euid;
1.20      thorpej  1107:        } */ *uap = v;
1.28      mycroft  1108:        struct sys_setreuid_args bsa;
1.18      fvdl     1109:
                   1110:        SCARG(&bsa, ruid) = ((linux_uid_t)SCARG(uap, ruid) == (linux_uid_t)-1) ?
                   1111:                (uid_t)-1 : SCARG(uap, ruid);
                   1112:        SCARG(&bsa, euid) = ((linux_uid_t)SCARG(uap, euid) == (linux_uid_t)-1) ?
                   1113:                (uid_t)-1 : SCARG(uap, euid);
                   1114:
1.28      mycroft  1115:        return sys_setreuid(p, &bsa, retval);
1.18      fvdl     1116: }
                   1117:
                   1118: int
1.21      mycroft  1119: linux_sys_setregid(p, v, retval)
1.18      fvdl     1120:        struct proc *p;
1.20      thorpej  1121:        void *v;
                   1122:        register_t *retval;
                   1123: {
1.21      mycroft  1124:        struct linux_sys_setregid_args /* {
1.18      fvdl     1125:                syscallarg(int) rgid;
                   1126:                syscallarg(int) egid;
1.20      thorpej  1127:        } */ *uap = v;
1.28      mycroft  1128:        struct sys_setregid_args bsa;
1.18      fvdl     1129:
                   1130:        SCARG(&bsa, rgid) = ((linux_gid_t)SCARG(uap, rgid) == (linux_gid_t)-1) ?
                   1131:                (uid_t)-1 : SCARG(uap, rgid);
                   1132:        SCARG(&bsa, egid) = ((linux_gid_t)SCARG(uap, egid) == (linux_gid_t)-1) ?
                   1133:                (uid_t)-1 : SCARG(uap, egid);
                   1134:
1.28      mycroft  1135:        return sys_setregid(p, &bsa, retval);
1.27      fvdl     1136: }
                   1137:
                   1138: int
                   1139: linux_sys___sysctl(p, v, retval)
                   1140:        struct proc *p;
                   1141:        void *v;
                   1142:        register_t *retval;
                   1143: {
                   1144:        struct linux_sys___sysctl_args /* {
                   1145:                syscallarg(struct linux___sysctl *) lsp;
                   1146:        } */ *uap = v;
                   1147:        struct linux___sysctl ls;
                   1148:        struct sys___sysctl_args bsa;
                   1149:        int error;
                   1150:
                   1151:        if ((error = copyin(SCARG(uap, lsp), &ls, sizeof ls)))
                   1152:                return error;
                   1153:        SCARG(&bsa, name) = ls.name;
                   1154:        SCARG(&bsa, namelen) = ls.namelen;
                   1155:        SCARG(&bsa, old) = ls.old;
                   1156:        SCARG(&bsa, oldlenp) = ls.oldlenp;
                   1157:        SCARG(&bsa, new) = ls.new;
                   1158:        SCARG(&bsa, newlen) = ls.newlen;
                   1159:
                   1160:        return sys___sysctl(p, &bsa, retval);
1.30      augustss 1161: }
                   1162:
                   1163: int
                   1164: linux_sys_nice(p, v, retval)
                   1165:        struct proc *p;
                   1166:        void *v;
                   1167:        register_t *retval;
                   1168: {
                   1169:        struct linux_sys_nice_args /* {
                   1170:                syscallarg(int) incr;
                   1171:        } */ *uap = v;
                   1172:         struct sys_setpriority_args bsa;
                   1173:
                   1174:         SCARG(&bsa, which) = PRIO_PROCESS;
                   1175:         SCARG(&bsa, who) = 0;
                   1176:        SCARG(&bsa, prio) = SCARG(uap, incr);
                   1177:         return sys_setpriority(p, &bsa, retval);
1.1       fvdl     1178: }

CVSweb <webmaster@jp.NetBSD.org>