The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/svr4/svr4_misc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1998 Mark Newton
    3  * Copyright (c) 1994 Christos Zoulas
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 /*
   29  * SVR4 compatibility module.
   30  *
   31  * SVR4 system calls that are implemented differently in BSD are
   32  * handled here.
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD: releng/7.4/sys/compat/svr4/svr4_misc.c 201413 2010-01-03 03:23:17Z delphij $");
   37 
   38 #include "opt_mac.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/dirent.h>
   43 #include <sys/fcntl.h>
   44 #include <sys/filedesc.h>
   45 #include <sys/imgact.h>
   46 #include <sys/kernel.h>
   47 #include <sys/lock.h>
   48 #include <sys/malloc.h>
   49 #include <sys/file.h>           /* Must come after sys/malloc.h */
   50 #include <sys/mman.h>
   51 #include <sys/mount.h>
   52 #include <sys/msg.h>
   53 #include <sys/mutex.h>
   54 #include <sys/namei.h>
   55 #include <sys/priv.h>
   56 #include <sys/proc.h>
   57 #include <sys/ptrace.h>
   58 #include <sys/resource.h>
   59 #include <sys/resourcevar.h>
   60 #include <sys/sem.h>
   61 #include <sys/signalvar.h>
   62 #include <sys/stat.h>
   63 #include <sys/sx.h>
   64 #include <sys/syscallsubr.h>
   65 #include <sys/sysproto.h>
   66 #include <sys/time.h>
   67 #include <sys/times.h>
   68 #include <sys/uio.h>
   69 #include <sys/vnode.h>
   70 #include <sys/wait.h>
   71 
   72 #include <compat/svr4/svr4.h>
   73 #include <compat/svr4/svr4_types.h>
   74 #include <compat/svr4/svr4_signal.h>
   75 #include <compat/svr4/svr4_proto.h>
   76 #include <compat/svr4/svr4_util.h>
   77 #include <compat/svr4/svr4_sysconfig.h>
   78 #include <compat/svr4/svr4_dirent.h>
   79 #include <compat/svr4/svr4_acl.h>
   80 #include <compat/svr4/svr4_ulimit.h>
   81 #include <compat/svr4/svr4_statvfs.h>
   82 #include <compat/svr4/svr4_hrt.h>
   83 #include <compat/svr4/svr4_mman.h>
   84 #include <compat/svr4/svr4_wait.h>
   85 
   86 #include <security/mac/mac_framework.h>
   87 
   88 #include <machine/vmparam.h>
   89 #include <vm/vm.h>
   90 #include <vm/vm_param.h>
   91 #include <vm/vm_map.h>
   92 #if defined(__FreeBSD__)
   93 #include <vm/uma.h>
   94 #include <vm/vm_extern.h>
   95 #endif
   96 
   97 #if defined(NetBSD)
   98 # if defined(UVM)
   99 #  include <uvm/uvm_extern.h>
  100 # endif
  101 #endif
  102 
  103 #define BSD_DIRENT(cp)          ((struct dirent *)(cp))
  104 
  105 static int svr4_mknod(struct thread *, register_t *, char *,
  106     svr4_mode_t, svr4_dev_t);
  107 
  108 static __inline clock_t timeval_to_clock_t(struct timeval *);
  109 static int svr4_setinfo (pid_t , struct rusage *, int, svr4_siginfo_t *);
  110 
  111 struct svr4_hrtcntl_args;
  112 static int svr4_hrtcntl (struct thread *, struct svr4_hrtcntl_args *,
  113     register_t *);
  114 static void bsd_statfs_to_svr4_statvfs(const struct statfs *,
  115     struct svr4_statvfs *);
  116 static void bsd_statfs_to_svr4_statvfs64(const struct statfs *,
  117     struct svr4_statvfs64 *);
  118 static struct proc *svr4_pfind(pid_t pid);
  119 
  120 /* BOGUS noop */
  121 #if defined(BOGUS)
  122 int
  123 svr4_sys_setitimer(td, uap)
  124         register struct thread *td;
  125         struct svr4_sys_setitimer_args *uap;
  126 {
  127         td->td_retval[0] = 0;
  128         return 0;
  129 }
  130 #endif
  131 
  132 int
  133 svr4_sys_wait(td, uap)
  134         struct thread *td;
  135         struct svr4_sys_wait_args *uap;
  136 {
  137         int error, st, sig;
  138 
  139         error = kern_wait(td, WAIT_ANY, &st, 0, NULL);
  140         if (error)
  141                 return (error);
  142       
  143         if (WIFSIGNALED(st)) {
  144                 sig = WTERMSIG(st);
  145                 if (sig >= 0 && sig < NSIG)
  146                         st = (st & ~0177) | SVR4_BSD2SVR4_SIG(sig);
  147         } else if (WIFSTOPPED(st)) {
  148                 sig = WSTOPSIG(st);
  149                 if (sig >= 0 && sig < NSIG)
  150                         st = (st & ~0xff00) | (SVR4_BSD2SVR4_SIG(sig) << 8);
  151         }
  152 
  153         /*
  154          * It looks like wait(2) on svr4/solaris/2.4 returns
  155          * the status in retval[1], and the pid on retval[0].
  156          */
  157         td->td_retval[1] = st;
  158 
  159         if (uap->status)
  160                 error = copyout(&st, uap->status, sizeof(st));
  161 
  162         return (error);
  163 }
  164 
  165 int
  166 svr4_sys_execv(td, uap)
  167         struct thread *td;
  168         struct svr4_sys_execv_args *uap;
  169 {
  170         struct image_args eargs;
  171         char *path;
  172         int error;
  173 
  174         CHECKALTEXIST(td, uap->path, &path);
  175 
  176         error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL);
  177         free(path, M_TEMP);
  178         if (error == 0)
  179                 error = kern_execve(td, &eargs, NULL);
  180         return (error);
  181 }
  182 
  183 int
  184 svr4_sys_execve(td, uap)
  185         struct thread *td;
  186         struct svr4_sys_execve_args *uap;
  187 {
  188         struct image_args eargs;
  189         char *path;
  190         int error;
  191 
  192         CHECKALTEXIST(td, uap->path, &path);
  193 
  194         error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp,
  195             uap->envp);
  196         free(path, M_TEMP);
  197         if (error == 0)
  198                 error = kern_execve(td, &eargs, NULL);
  199         return (error);
  200 }
  201 
  202 int
  203 svr4_sys_time(td, v)
  204         struct thread *td;
  205         struct svr4_sys_time_args *v;
  206 {
  207         struct svr4_sys_time_args *uap = v;
  208         int error = 0;
  209         struct timeval tv;
  210 
  211         microtime(&tv);
  212         if (uap->t)
  213                 error = copyout(&tv.tv_sec, uap->t,
  214                                 sizeof(*(uap->t)));
  215         td->td_retval[0] = (int) tv.tv_sec;
  216 
  217         return error;
  218 }
  219 
  220 
  221 /*
  222  * Read SVR4-style directory entries.  We suck them into kernel space so
  223  * that they can be massaged before being copied out to user code.  
  224  *
  225  * This code is ported from the Linux emulator:  Changes to the VFS interface
  226  * between FreeBSD and NetBSD have made it simpler to port it from there than
  227  * to adapt the NetBSD version.
  228  */
  229 int
  230 svr4_sys_getdents64(td, uap)
  231         struct thread *td;
  232         struct svr4_sys_getdents64_args *uap;
  233 {
  234         register struct dirent *bdp;
  235         struct vnode *vp;
  236         caddr_t inp, buf;               /* BSD-format */
  237         int len, reclen;                /* BSD-format */
  238         caddr_t outp;                   /* SVR4-format */
  239         int resid, svr4reclen=0;        /* SVR4-format */
  240         struct file *fp;
  241         struct uio auio;
  242         struct iovec aiov;
  243         off_t off;
  244         struct svr4_dirent64 svr4_dirent;
  245         int buflen, error, eofflag, nbytes, justone, vfslocked;
  246         u_long *cookies = NULL, *cookiep;
  247         int ncookies;
  248 
  249         DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n",
  250                 uap->fd, uap->nbytes));
  251         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) {
  252                 return (error);
  253         }
  254 
  255         if ((fp->f_flag & FREAD) == 0) {
  256                 fdrop(fp, td);
  257                 return (EBADF);
  258         }
  259 
  260         vp = fp->f_vnode;
  261         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  262         if (vp->v_type != VDIR) {
  263                 VFS_UNLOCK_GIANT(vfslocked);
  264                 fdrop(fp, td);
  265                 return (EINVAL);
  266         }
  267 
  268         nbytes = uap->nbytes;
  269         if (nbytes == 1) {
  270                 nbytes = sizeof (struct svr4_dirent64);
  271                 justone = 1;
  272         }
  273         else
  274                 justone = 0;
  275 
  276         off = fp->f_offset;
  277 #define DIRBLKSIZ       512             /* XXX we used to use ufs's DIRBLKSIZ */
  278         buflen = max(DIRBLKSIZ, nbytes);
  279         buflen = min(buflen, MAXBSIZE);
  280         buf = malloc(buflen, M_TEMP, M_WAITOK);
  281         vn_lock(vp, LK_SHARED | LK_RETRY, td);
  282 again:
  283         aiov.iov_base = buf;
  284         aiov.iov_len = buflen;
  285         auio.uio_iov = &aiov;
  286         auio.uio_iovcnt = 1;
  287         auio.uio_rw = UIO_READ;
  288         auio.uio_segflg = UIO_SYSSPACE;
  289         auio.uio_td = td;
  290         auio.uio_resid = buflen;
  291         auio.uio_offset = off;
  292 
  293         if (cookies) {
  294                 free(cookies, M_TEMP);
  295                 cookies = NULL;
  296         }
  297 
  298 #ifdef MAC
  299         error = mac_check_vnode_readdir(td->td_ucred, vp);
  300         if (error)
  301                 goto out;
  302 #endif
  303 
  304         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
  305                                                 &ncookies, &cookies);
  306         if (error) {
  307                 goto out;
  308         }
  309 
  310         inp = buf;
  311         outp = (caddr_t) uap->dp;
  312         resid = nbytes;
  313         if ((len = buflen - auio.uio_resid) <= 0) {
  314                 goto eof;
  315         }
  316 
  317         cookiep = cookies;
  318 
  319         if (cookies) {
  320                 /*
  321                  * When using cookies, the vfs has the option of reading from
  322                  * a different offset than that supplied (UFS truncates the
  323                  * offset to a block boundary to make sure that it never reads
  324                  * partway through a directory entry, even if the directory
  325                  * has been compacted).
  326                  */
  327                 while (len > 0 && ncookies > 0 && *cookiep <= off) {
  328                         bdp = (struct dirent *) inp;
  329                         len -= bdp->d_reclen;
  330                         inp += bdp->d_reclen;
  331                         cookiep++;
  332                         ncookies--;
  333                 }
  334         }
  335 
  336         while (len > 0) {
  337                 if (cookiep && ncookies == 0)
  338                         break;
  339                 bdp = (struct dirent *) inp;
  340                 reclen = bdp->d_reclen;
  341                 if (reclen & 3) {
  342                         DPRINTF(("svr4_readdir: reclen=%d\n", reclen));
  343                         error = EFAULT;
  344                         goto out;
  345                 }
  346   
  347                 if (bdp->d_fileno == 0) {
  348                         inp += reclen;
  349                         if (cookiep) {
  350                                 off = *cookiep++;
  351                                 ncookies--;
  352                         } else
  353                                 off += reclen;
  354                         len -= reclen;
  355                         continue;
  356                 }
  357                 svr4reclen = SVR4_RECLEN(&svr4_dirent, bdp->d_namlen);
  358                 if (reclen > len || resid < svr4reclen) {
  359                         outp++;
  360                         break;
  361                 }
  362                 svr4_dirent.d_ino = (long) bdp->d_fileno;
  363                 if (justone) {
  364                         /*
  365                          * old svr4-style readdir usage.
  366                          */
  367                         svr4_dirent.d_off = (svr4_off_t) svr4reclen;
  368                         svr4_dirent.d_reclen = (u_short) bdp->d_namlen;
  369                 } else {
  370                         svr4_dirent.d_off = (svr4_off_t)(off + reclen);
  371                         svr4_dirent.d_reclen = (u_short) svr4reclen;
  372                 }
  373                 strcpy(svr4_dirent.d_name, bdp->d_name);
  374                 if ((error = copyout((caddr_t)&svr4_dirent, outp, svr4reclen)))
  375                         goto out;
  376                 inp += reclen;
  377                 if (cookiep) {
  378                         off = *cookiep++;
  379                         ncookies--;
  380                 } else
  381                         off += reclen;
  382                 outp += svr4reclen;
  383                 resid -= svr4reclen;
  384                 len -= reclen;
  385                 if (justone)
  386                         break;
  387         }
  388 
  389         if (outp == (caddr_t) uap->dp)
  390                 goto again;
  391         fp->f_offset = off;
  392 
  393         if (justone)
  394                 nbytes = resid + svr4reclen;
  395 
  396 eof:
  397         td->td_retval[0] = nbytes - resid;
  398 out:
  399         VOP_UNLOCK(vp, 0, td);
  400         VFS_UNLOCK_GIANT(vfslocked);
  401         fdrop(fp, td);
  402         if (cookies)
  403                 free(cookies, M_TEMP);
  404         free(buf, M_TEMP);
  405         return error;
  406 }
  407 
  408 
  409 int
  410 svr4_sys_getdents(td, uap)
  411         struct thread *td;
  412         struct svr4_sys_getdents_args *uap;
  413 {
  414         struct dirent *bdp;
  415         struct vnode *vp;
  416         caddr_t inp, buf;       /* BSD-format */
  417         int len, reclen;        /* BSD-format */
  418         caddr_t outp;           /* SVR4-format */
  419         int resid, svr4_reclen; /* SVR4-format */
  420         struct file *fp;
  421         struct uio auio;
  422         struct iovec aiov;
  423         struct svr4_dirent idb;
  424         off_t off;              /* true file offset */
  425         int buflen, error, eofflag, vfslocked;
  426         u_long *cookiebuf = NULL, *cookie;
  427         int ncookies = 0, *retval = td->td_retval;
  428 
  429         if (uap->nbytes < 0)
  430                 return (EINVAL);
  431 
  432         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
  433                 return (error);
  434 
  435         if ((fp->f_flag & FREAD) == 0) {
  436                 fdrop(fp, td);
  437                 return (EBADF);
  438         }
  439 
  440         vp = fp->f_vnode;
  441         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  442         if (vp->v_type != VDIR) {
  443                 VFS_UNLOCK_GIANT(vfslocked);
  444                 fdrop(fp, td);
  445                 return (EINVAL);
  446         }
  447 
  448         buflen = min(MAXBSIZE, uap->nbytes);
  449         buf = malloc(buflen, M_TEMP, M_WAITOK);
  450         vn_lock(vp, LK_SHARED | LK_RETRY, td);
  451         off = fp->f_offset;
  452 again:
  453         aiov.iov_base = buf;
  454         aiov.iov_len = buflen;
  455         auio.uio_iov = &aiov;
  456         auio.uio_iovcnt = 1;
  457         auio.uio_rw = UIO_READ;
  458         auio.uio_segflg = UIO_SYSSPACE;
  459         auio.uio_td = td;
  460         auio.uio_resid = buflen;
  461         auio.uio_offset = off;
  462 
  463 #ifdef MAC
  464         error = mac_check_vnode_readdir(td->td_ucred, vp);
  465         if (error)
  466                 goto out;
  467 #endif
  468 
  469         /*
  470          * First we read into the malloc'ed buffer, then
  471          * we massage it into user space, one record at a time.
  472          */
  473         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
  474             &cookiebuf);
  475         if (error) {
  476                 goto out;
  477         }
  478 
  479         inp = buf;
  480         outp = uap->buf;
  481         resid = uap->nbytes;
  482         if ((len = buflen - auio.uio_resid) == 0)
  483                 goto eof;
  484 
  485         for (cookie = cookiebuf; len > 0; len -= reclen) {
  486                 bdp = (struct dirent *)inp;
  487                 reclen = bdp->d_reclen;
  488                 if (reclen & 3)
  489                         panic("svr4_sys_getdents64: bad reclen");
  490                 off = *cookie++;        /* each entry points to the next */
  491                 if ((off >> 32) != 0) {
  492                         uprintf("svr4_sys_getdents64: dir offset too large for emulated program");
  493                         error = EINVAL;
  494                         goto out;
  495                 }
  496                 if (bdp->d_fileno == 0) {
  497                         inp += reclen;  /* it is a hole; squish it out */
  498                         continue;
  499                 }
  500                 svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
  501                 if (reclen > len || resid < svr4_reclen) {
  502                         /* entry too big for buffer, so just stop */
  503                         outp++;
  504                         break;
  505                 }
  506                 /*
  507                  * Massage in place to make a SVR4-shaped dirent (otherwise
  508                  * we have to worry about touching user memory outside of
  509                  * the copyout() call).
  510                  */
  511                 idb.d_ino = (svr4_ino_t)bdp->d_fileno;
  512                 idb.d_off = (svr4_off_t)off;
  513                 idb.d_reclen = (u_short)svr4_reclen;
  514                 strcpy(idb.d_name, bdp->d_name);
  515                 if ((error = copyout((caddr_t)&idb, outp, svr4_reclen)))
  516                         goto out;
  517                 /* advance past this real entry */
  518                 inp += reclen;
  519                 /* advance output past SVR4-shaped entry */
  520                 outp += svr4_reclen;
  521                 resid -= svr4_reclen;
  522         }
  523 
  524         /* if we squished out the whole block, try again */
  525         if (outp == uap->buf)
  526                 goto again;
  527         fp->f_offset = off;     /* update the vnode offset */
  528 
  529 eof:
  530         *retval = uap->nbytes - resid;
  531 out:
  532         VOP_UNLOCK(vp, 0, td);
  533         VFS_UNLOCK_GIANT(vfslocked);
  534         fdrop(fp, td);
  535         if (cookiebuf)
  536                 free(cookiebuf, M_TEMP);
  537         free(buf, M_TEMP);
  538         return error;
  539 }
  540 
  541 
  542 int
  543 svr4_sys_mmap(td, uap)
  544         struct thread *td;
  545         struct svr4_sys_mmap_args *uap;
  546 {
  547         struct mmap_args         mm;
  548         int             *retval;
  549 
  550         retval = td->td_retval;
  551 #define _MAP_NEW        0x80000000
  552         /*
  553          * Verify the arguments.
  554          */
  555         if (uap->prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
  556                 return EINVAL;  /* XXX still needed? */
  557 
  558         if (uap->len == 0)
  559                 return EINVAL;
  560 
  561         mm.prot = uap->prot;
  562         mm.len = uap->len;
  563         mm.flags = uap->flags & ~_MAP_NEW;
  564         mm.fd = uap->fd;
  565         mm.addr = uap->addr;
  566         mm.pos = uap->pos;
  567 
  568         return mmap(td, &mm);
  569 }
  570 
  571 int
  572 svr4_sys_mmap64(td, uap)
  573         struct thread *td;
  574         struct svr4_sys_mmap64_args *uap;
  575 {
  576         struct mmap_args         mm;
  577         void            *rp;
  578 
  579 #define _MAP_NEW        0x80000000
  580         /*
  581          * Verify the arguments.
  582          */
  583         if (uap->prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
  584                 return EINVAL;  /* XXX still needed? */
  585 
  586         if (uap->len == 0)
  587                 return EINVAL;
  588 
  589         mm.prot = uap->prot;
  590         mm.len = uap->len;
  591         mm.flags = uap->flags & ~_MAP_NEW;
  592         mm.fd = uap->fd;
  593         mm.addr = uap->addr;
  594         mm.pos = uap->pos;
  595 
  596         rp = (void *) round_page((vm_offset_t)(td->td_proc->p_vmspace->vm_daddr + maxdsiz));
  597         if ((mm.flags & MAP_FIXED) == 0 &&
  598             mm.addr != 0 && (void *)mm.addr < rp)
  599                 mm.addr = rp;
  600 
  601         return mmap(td, &mm);
  602 }
  603 
  604 
  605 int
  606 svr4_sys_fchroot(td, uap)
  607         struct thread *td;
  608         struct svr4_sys_fchroot_args *uap;
  609 {
  610         struct filedesc *fdp = td->td_proc->p_fd;
  611         struct vnode    *vp;
  612         struct file     *fp;
  613         int              error, vfslocked;
  614 
  615         if ((error = priv_check(td, PRIV_VFS_FCHROOT)) != 0)
  616                 return error;
  617         if ((error = getvnode(fdp, uap->fd, &fp)) != 0)
  618                 return error;
  619         vp = fp->f_vnode;
  620         VREF(vp);
  621         fdrop(fp, td);
  622         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  623         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  624         error = change_dir(vp, td);
  625         if (error)
  626                 goto fail;
  627 #ifdef MAC
  628         error = mac_check_vnode_chroot(td->td_ucred, vp);
  629         if (error)
  630                 goto fail;
  631 #endif
  632         VOP_UNLOCK(vp, 0, td);
  633         error = change_root(vp, td);
  634         vrele(vp);
  635         VFS_UNLOCK_GIANT(vfslocked);
  636         return (error);
  637 fail:
  638         vput(vp);
  639         VFS_UNLOCK_GIANT(vfslocked);
  640         return (error);
  641 }
  642 
  643 
  644 static int
  645 svr4_mknod(td, retval, path, mode, dev)
  646         struct thread *td;
  647         register_t *retval;
  648         char *path;
  649         svr4_mode_t mode;
  650         svr4_dev_t dev;
  651 {
  652         char *newpath;
  653         int error;
  654 
  655         CHECKALTEXIST(td, path, &newpath);
  656 
  657         if (S_ISFIFO(mode))
  658                 error = kern_mkfifo(td, newpath, UIO_SYSSPACE, mode);
  659         else
  660                 error = kern_mknod(td, newpath, UIO_SYSSPACE, mode, dev);
  661         free(newpath, M_TEMP);
  662         return (error);
  663 }
  664 
  665 
  666 int
  667 svr4_sys_mknod(td, uap)
  668         register struct thread *td;
  669         struct svr4_sys_mknod_args *uap;
  670 {
  671         int *retval = td->td_retval;
  672         return svr4_mknod(td, retval,
  673                           uap->path, uap->mode,
  674                           (svr4_dev_t)svr4_to_bsd_odev_t(uap->dev));
  675 }
  676 
  677 
  678 int
  679 svr4_sys_xmknod(td, uap)
  680         struct thread *td;
  681         struct svr4_sys_xmknod_args *uap;
  682 {
  683         int *retval = td->td_retval;
  684         return svr4_mknod(td, retval,
  685                           uap->path, uap->mode,
  686                           (svr4_dev_t)svr4_to_bsd_dev_t(uap->dev));
  687 }
  688 
  689 
  690 int
  691 svr4_sys_vhangup(td, uap)
  692         struct thread *td;
  693         struct svr4_sys_vhangup_args *uap;
  694 {
  695         return 0;
  696 }
  697 
  698 
  699 int
  700 svr4_sys_sysconfig(td, uap)
  701         struct thread *td;
  702         struct svr4_sys_sysconfig_args *uap;
  703 {
  704         int *retval;
  705 
  706         retval = &(td->td_retval[0]);
  707 
  708         switch (uap->name) {
  709         case SVR4_CONFIG_NGROUPS:
  710                 *retval = NGROUPS_MAX;
  711                 break;
  712         case SVR4_CONFIG_CHILD_MAX:
  713                 *retval = maxproc;
  714                 break;
  715         case SVR4_CONFIG_OPEN_FILES:
  716                 *retval = maxfiles;
  717                 break;
  718         case SVR4_CONFIG_POSIX_VER:
  719                 *retval = 198808;
  720                 break;
  721         case SVR4_CONFIG_PAGESIZE:
  722                 *retval = PAGE_SIZE;
  723                 break;
  724         case SVR4_CONFIG_CLK_TCK:
  725                 *retval = 60;   /* should this be `hz', ie. 100? */
  726                 break;
  727         case SVR4_CONFIG_XOPEN_VER:
  728                 *retval = 2;    /* XXX: What should that be? */
  729                 break;
  730         case SVR4_CONFIG_PROF_TCK:
  731                 *retval = 60;   /* XXX: What should that be? */
  732                 break;
  733         case SVR4_CONFIG_NPROC_CONF:
  734                 *retval = 1;    /* Only one processor for now */
  735                 break;
  736         case SVR4_CONFIG_NPROC_ONLN:
  737                 *retval = 1;    /* And it better be online */
  738                 break;
  739         case SVR4_CONFIG_AIO_LISTIO_MAX:
  740         case SVR4_CONFIG_AIO_MAX:
  741         case SVR4_CONFIG_AIO_PRIO_DELTA_MAX:
  742                 *retval = 0;    /* No aio support */
  743                 break;
  744         case SVR4_CONFIG_DELAYTIMER_MAX:
  745                 *retval = 0;    /* No delaytimer support */
  746                 break;
  747         case SVR4_CONFIG_MQ_OPEN_MAX:
  748                 *retval = msginfo.msgmni;
  749                 break;
  750         case SVR4_CONFIG_MQ_PRIO_MAX:
  751                 *retval = 0;    /* XXX: Don't know */
  752                 break;
  753         case SVR4_CONFIG_RTSIG_MAX:
  754                 *retval = 0;
  755                 break;
  756         case SVR4_CONFIG_SEM_NSEMS_MAX:
  757                 *retval = seminfo.semmni;
  758                 break;
  759         case SVR4_CONFIG_SEM_VALUE_MAX:
  760                 *retval = seminfo.semvmx;
  761                 break;
  762         case SVR4_CONFIG_SIGQUEUE_MAX:
  763                 *retval = 0;    /* XXX: Don't know */
  764                 break;
  765         case SVR4_CONFIG_SIGRT_MIN:
  766         case SVR4_CONFIG_SIGRT_MAX:
  767                 *retval = 0;    /* No real time signals */
  768                 break;
  769         case SVR4_CONFIG_TIMER_MAX:
  770                 *retval = 3;    /* XXX: real, virtual, profiling */
  771                 break;
  772 #if defined(NOTYET)
  773         case SVR4_CONFIG_PHYS_PAGES:
  774 #if defined(UVM)
  775                 *retval = uvmexp.free;  /* XXX: free instead of total */
  776 #else
  777                 *retval = cnt.v_free_count;     /* XXX: free instead of total */
  778 #endif
  779                 break;
  780         case SVR4_CONFIG_AVPHYS_PAGES:
  781 #if defined(UVM)
  782                 *retval = uvmexp.active;        /* XXX: active instead of avg */
  783 #else
  784                 *retval = cnt.v_active_count;   /* XXX: active instead of avg */
  785 #endif
  786                 break;
  787 #endif /* NOTYET */
  788         case SVR4_CONFIG_COHERENCY:
  789                 *retval = 0;    /* XXX */
  790                 break;
  791         case SVR4_CONFIG_SPLIT_CACHE:
  792                 *retval = 0;    /* XXX */
  793                 break;
  794         case SVR4_CONFIG_ICACHESZ:
  795                 *retval = 256;  /* XXX */
  796                 break;
  797         case SVR4_CONFIG_DCACHESZ:
  798                 *retval = 256;  /* XXX */
  799                 break;
  800         case SVR4_CONFIG_ICACHELINESZ:
  801                 *retval = 64;   /* XXX */
  802                 break;
  803         case SVR4_CONFIG_DCACHELINESZ:
  804                 *retval = 64;   /* XXX */
  805                 break;
  806         case SVR4_CONFIG_ICACHEBLKSZ:
  807                 *retval = 64;   /* XXX */
  808                 break;
  809         case SVR4_CONFIG_DCACHEBLKSZ:
  810                 *retval = 64;   /* XXX */
  811                 break;
  812         case SVR4_CONFIG_DCACHETBLKSZ:
  813                 *retval = 64;   /* XXX */
  814                 break;
  815         case SVR4_CONFIG_ICACHE_ASSOC:
  816                 *retval = 1;    /* XXX */
  817                 break;
  818         case SVR4_CONFIG_DCACHE_ASSOC:
  819                 *retval = 1;    /* XXX */
  820                 break;
  821         case SVR4_CONFIG_MAXPID:
  822                 *retval = PID_MAX;
  823                 break;
  824         case SVR4_CONFIG_STACK_PROT:
  825                 *retval = PROT_READ|PROT_WRITE|PROT_EXEC;
  826                 break;
  827         default:
  828                 return EINVAL;
  829         }
  830         return 0;
  831 }
  832 
  833 /* ARGSUSED */
  834 int
  835 svr4_sys_break(td, uap)
  836         struct thread *td;
  837         struct svr4_sys_break_args *uap;
  838 {
  839         struct obreak_args ap;
  840 
  841         ap.nsize = uap->nsize;
  842         return (obreak(td, &ap));
  843 }
  844 
  845 static __inline clock_t
  846 timeval_to_clock_t(tv)
  847         struct timeval *tv;
  848 {
  849         return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz);
  850 }
  851 
  852 
  853 int
  854 svr4_sys_times(td, uap)
  855         struct thread *td;
  856         struct svr4_sys_times_args *uap;
  857 {
  858         struct timeval tv, utime, stime, cutime, cstime;
  859         struct tms tms;
  860         struct proc *p;
  861         int error;
  862 
  863         p = td->td_proc;
  864         PROC_LOCK(p);
  865         PROC_SLOCK(p);
  866         calcru(p, &utime, &stime);
  867         PROC_SUNLOCK(p);
  868         calccru(p, &cutime, &cstime);
  869         PROC_UNLOCK(p);
  870 
  871         tms.tms_utime = timeval_to_clock_t(&utime);
  872         tms.tms_stime = timeval_to_clock_t(&stime);
  873 
  874         tms.tms_cutime = timeval_to_clock_t(&cutime);
  875         tms.tms_cstime = timeval_to_clock_t(&cstime);
  876 
  877         error = copyout(&tms, uap->tp, sizeof(tms));
  878         if (error)
  879                 return (error);
  880 
  881         microtime(&tv);
  882         td->td_retval[0] = (int)timeval_to_clock_t(&tv);
  883         return (0);
  884 }
  885 
  886 
  887 int
  888 svr4_sys_ulimit(td, uap)
  889         struct thread *td;
  890         struct svr4_sys_ulimit_args *uap;
  891 {
  892         int *retval = td->td_retval;
  893         int error;
  894 
  895         switch (uap->cmd) {
  896         case SVR4_GFILLIM:
  897                 PROC_LOCK(td->td_proc);
  898                 *retval = lim_cur(td->td_proc, RLIMIT_FSIZE) / 512;
  899                 PROC_UNLOCK(td->td_proc);
  900                 if (*retval == -1)
  901                         *retval = 0x7fffffff;
  902                 return 0;
  903 
  904         case SVR4_SFILLIM:
  905                 {
  906                         struct rlimit krl;
  907 
  908                         krl.rlim_cur = uap->newlimit * 512;
  909                         PROC_LOCK(td->td_proc);
  910                         krl.rlim_max = lim_max(td->td_proc, RLIMIT_FSIZE);
  911                         PROC_UNLOCK(td->td_proc);
  912 
  913                         error = kern_setrlimit(td, RLIMIT_FSIZE, &krl);
  914                         if (error)
  915                                 return error;
  916 
  917                         PROC_LOCK(td->td_proc);
  918                         *retval = lim_cur(td->td_proc, RLIMIT_FSIZE);
  919                         PROC_UNLOCK(td->td_proc);
  920                         if (*retval == -1)
  921                                 *retval = 0x7fffffff;
  922                         return 0;
  923                 }
  924 
  925         case SVR4_GMEMLIM:
  926                 {
  927                         struct vmspace *vm = td->td_proc->p_vmspace;
  928                         register_t r;
  929 
  930                         PROC_LOCK(td->td_proc);
  931                         r = lim_cur(td->td_proc, RLIMIT_DATA);
  932                         PROC_UNLOCK(td->td_proc);
  933 
  934                         if (r == -1)
  935                                 r = 0x7fffffff;
  936                         mtx_lock(&Giant);       /* XXX */
  937                         r += (long) vm->vm_daddr;
  938                         mtx_unlock(&Giant);
  939                         if (r < 0)
  940                                 r = 0x7fffffff;
  941                         *retval = r;
  942                         return 0;
  943                 }
  944 
  945         case SVR4_GDESLIM:
  946                 PROC_LOCK(td->td_proc);
  947                 *retval = lim_cur(td->td_proc, RLIMIT_NOFILE);
  948                 PROC_UNLOCK(td->td_proc);
  949                 if (*retval == -1)
  950                         *retval = 0x7fffffff;
  951                 return 0;
  952 
  953         default:
  954                 return EINVAL;
  955         }
  956 }
  957 
  958 static struct proc *
  959 svr4_pfind(pid)
  960         pid_t pid;
  961 {
  962         struct proc *p;
  963 
  964         /* look in the live processes */
  965         if ((p = pfind(pid)) == NULL)
  966                 /* look in the zombies */
  967                 p = zpfind(pid);
  968 
  969         return p;
  970 }
  971 
  972 
  973 int
  974 svr4_sys_pgrpsys(td, uap)
  975         struct thread *td;
  976         struct svr4_sys_pgrpsys_args *uap;
  977 {
  978         int *retval = td->td_retval;
  979         struct proc *p = td->td_proc;
  980 
  981         switch (uap->cmd) {
  982         case 1:                 /* setpgrp() */
  983                 /*
  984                  * SVR4 setpgrp() (which takes no arguments) has the
  985                  * semantics that the session ID is also created anew, so
  986                  * in almost every sense, setpgrp() is identical to
  987                  * setsid() for SVR4.  (Under BSD, the difference is that
  988                  * a setpgid(0,0) will not create a new session.)
  989                  */
  990                 setsid(td, NULL);
  991                 /*FALLTHROUGH*/
  992 
  993         case 0:                 /* getpgrp() */
  994                 PROC_LOCK(p);
  995                 *retval = p->p_pgrp->pg_id;
  996                 PROC_UNLOCK(p);
  997                 return 0;
  998 
  999         case 2:                 /* getsid(pid) */
 1000                 if (uap->pid == 0)
 1001                         PROC_LOCK(p);
 1002                 else if ((p = svr4_pfind(uap->pid)) == NULL)
 1003                         return ESRCH;
 1004                 /*
 1005                  * This has already been initialized to the pid of
 1006                  * the session leader.
 1007                  */
 1008                 *retval = (register_t) p->p_session->s_sid;
 1009                 PROC_UNLOCK(p);
 1010                 return 0;
 1011 
 1012         case 3:                 /* setsid() */
 1013                 return setsid(td, NULL);
 1014 
 1015         case 4:                 /* getpgid(pid) */
 1016 
 1017                 if (uap->pid == 0)
 1018                         PROC_LOCK(p);
 1019                 else if ((p = svr4_pfind(uap->pid)) == NULL)
 1020                         return ESRCH;
 1021 
 1022                 *retval = (int) p->p_pgrp->pg_id;
 1023                 PROC_UNLOCK(p);
 1024                 return 0;
 1025 
 1026         case 5:                 /* setpgid(pid, pgid); */
 1027                 {
 1028                         struct setpgid_args sa;
 1029 
 1030                         sa.pid = uap->pid;
 1031                         sa.pgid = uap->pgid;
 1032                         return setpgid(td, &sa);
 1033                 }
 1034 
 1035         default:
 1036                 return EINVAL;
 1037         }
 1038 }
 1039 
 1040 struct svr4_hrtcntl_args {
 1041         int                     cmd;
 1042         int                     fun;
 1043         int                     clk;
 1044         svr4_hrt_interval_t *   iv;
 1045         svr4_hrt_time_t *       ti;
 1046 };
 1047 
 1048 
 1049 static int
 1050 svr4_hrtcntl(td, uap, retval)
 1051         struct thread *td;
 1052         struct svr4_hrtcntl_args *uap;
 1053         register_t *retval;
 1054 {
 1055         switch (uap->fun) {
 1056         case SVR4_HRT_CNTL_RES:
 1057                 DPRINTF(("htrcntl(RES)\n"));
 1058                 *retval = SVR4_HRT_USEC;
 1059                 return 0;
 1060 
 1061         case SVR4_HRT_CNTL_TOFD:
 1062                 DPRINTF(("htrcntl(TOFD)\n"));
 1063                 {
 1064                         struct timeval tv;
 1065                         svr4_hrt_time_t t;
 1066                         if (uap->clk != SVR4_HRT_CLK_STD) {
 1067                                 DPRINTF(("clk == %d\n", uap->clk));
 1068                                 return EINVAL;
 1069                         }
 1070                         if (uap->ti == NULL) {
 1071                                 DPRINTF(("ti NULL\n"));
 1072                                 return EINVAL;
 1073                         }
 1074                         microtime(&tv);
 1075                         t.h_sec = tv.tv_sec;
 1076                         t.h_rem = tv.tv_usec;
 1077                         t.h_res = SVR4_HRT_USEC;
 1078                         return copyout(&t, uap->ti, sizeof(t));
 1079                 }
 1080 
 1081         case SVR4_HRT_CNTL_START:
 1082                 DPRINTF(("htrcntl(START)\n"));
 1083                 return ENOSYS;
 1084 
 1085         case SVR4_HRT_CNTL_GET:
 1086                 DPRINTF(("htrcntl(GET)\n"));
 1087                 return ENOSYS;
 1088         default:
 1089                 DPRINTF(("Bad htrcntl command %d\n", uap->fun));
 1090                 return ENOSYS;
 1091         }
 1092 }
 1093 
 1094 
 1095 int
 1096 svr4_sys_hrtsys(td, uap) 
 1097         struct thread *td;
 1098         struct svr4_sys_hrtsys_args *uap;
 1099 {
 1100         int *retval = td->td_retval;
 1101 
 1102         switch (uap->cmd) {
 1103         case SVR4_HRT_CNTL:
 1104                 return svr4_hrtcntl(td, (struct svr4_hrtcntl_args *) uap,
 1105                                     retval);
 1106 
 1107         case SVR4_HRT_ALRM:
 1108                 DPRINTF(("hrtalarm\n"));
 1109                 return ENOSYS;
 1110 
 1111         case SVR4_HRT_SLP:
 1112                 DPRINTF(("hrtsleep\n"));
 1113                 return ENOSYS;
 1114 
 1115         case SVR4_HRT_CAN:
 1116                 DPRINTF(("hrtcancel\n"));
 1117                 return ENOSYS;
 1118 
 1119         default:
 1120                 DPRINTF(("Bad hrtsys command %d\n", uap->cmd));
 1121                 return EINVAL;
 1122         }
 1123 }
 1124 
 1125 
 1126 static int
 1127 svr4_setinfo(pid, ru, st, s)
 1128         pid_t pid;
 1129         struct rusage *ru;
 1130         int st;
 1131         svr4_siginfo_t *s;
 1132 {
 1133         svr4_siginfo_t i;
 1134         int sig;
 1135 
 1136         memset(&i, 0, sizeof(i));
 1137 
 1138         i.svr4_si_signo = SVR4_SIGCHLD;
 1139         i.svr4_si_errno = 0;    /* XXX? */
 1140 
 1141         i.svr4_si_pid = pid;
 1142         if (ru) {
 1143                 i.svr4_si_stime = ru->ru_stime.tv_sec;
 1144                 i.svr4_si_utime = ru->ru_utime.tv_sec;
 1145         }
 1146 
 1147         if (WIFEXITED(st)) {
 1148                 i.svr4_si_status = WEXITSTATUS(st);
 1149                 i.svr4_si_code = SVR4_CLD_EXITED;
 1150         } else if (WIFSTOPPED(st)) {
 1151                 sig = WSTOPSIG(st);
 1152                 if (sig >= 0 && sig < NSIG)
 1153                         i.svr4_si_status = SVR4_BSD2SVR4_SIG(sig);
 1154 
 1155                 if (i.svr4_si_status == SVR4_SIGCONT)
 1156                         i.svr4_si_code = SVR4_CLD_CONTINUED;
 1157                 else
 1158                         i.svr4_si_code = SVR4_CLD_STOPPED;
 1159         } else {
 1160                 sig = WTERMSIG(st);
 1161                 if (sig >= 0 && sig < NSIG)
 1162                         i.svr4_si_status = SVR4_BSD2SVR4_SIG(sig);
 1163 
 1164                 if (WCOREDUMP(st))
 1165                         i.svr4_si_code = SVR4_CLD_DUMPED;
 1166                 else
 1167                         i.svr4_si_code = SVR4_CLD_KILLED;
 1168         }
 1169 
 1170         DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n",
 1171                  i.svr4_si_pid, i.svr4_si_signo, i.svr4_si_code, i.svr4_si_errno,
 1172                  i.svr4_si_status));
 1173 
 1174         return copyout(&i, s, sizeof(i));
 1175 }
 1176 
 1177 
 1178 int
 1179 svr4_sys_waitsys(td, uap)
 1180         struct thread *td;
 1181         struct svr4_sys_waitsys_args *uap;
 1182 {
 1183         struct rusage ru;
 1184         pid_t pid;
 1185         int nfound, status;
 1186         int error, *retval = td->td_retval;
 1187         struct proc *p, *q;
 1188 
 1189         DPRINTF(("waitsys(%d, %d, %p, %x)\n", 
 1190                  uap->grp, uap->id,
 1191                  uap->info, uap->options));
 1192 
 1193         q = td->td_proc;
 1194         switch (uap->grp) {
 1195         case SVR4_P_PID:
 1196                 pid = uap->id;
 1197                 break;
 1198 
 1199         case SVR4_P_PGID:
 1200                 PROC_LOCK(q);
 1201                 pid = -q->p_pgid;
 1202                 PROC_UNLOCK(q);
 1203                 break;
 1204 
 1205         case SVR4_P_ALL:
 1206                 pid = WAIT_ANY;
 1207                 break;
 1208 
 1209         default:
 1210                 return EINVAL;
 1211         }
 1212 
 1213         /* Hand off the easy cases to kern_wait(). */
 1214         if (!(uap->options & (SVR4_WNOWAIT)) &&
 1215             (uap->options & (SVR4_WEXITED | SVR4_WTRAPPED))) {
 1216                 int options;
 1217 
 1218                 options = 0;
 1219                 if (uap->options & SVR4_WSTOPPED)
 1220                         options |= WUNTRACED;
 1221                 if (uap->options & SVR4_WCONTINUED)
 1222                         options |= WCONTINUED;
 1223                 if (uap->options & SVR4_WNOHANG)
 1224                         options |= WNOHANG;
 1225 
 1226                 error = kern_wait(td, pid, &status, options, &ru);
 1227                 if (error)
 1228                         return (error);
 1229                 if (uap->options & SVR4_WNOHANG && *retval == 0)
 1230                         error = svr4_setinfo(*retval, NULL, 0, uap->info);
 1231                 else
 1232                         error = svr4_setinfo(*retval, &ru, status, uap->info);
 1233                 *retval = 0;
 1234                 return (error);
 1235         }
 1236 
 1237         /*
 1238          * Ok, handle the weird cases.  Either WNOWAIT is set (meaning we
 1239          * just want to see if there is a process to harvest, we dont'
 1240          * want to actually harvest it), or WEXIT and WTRAPPED are clear
 1241          * meaning we want to ignore zombies.  Either way, we don't have
 1242          * to handle harvesting zombies here.  We do have to duplicate the
 1243          * other portions of kern_wait() though, especially for the
 1244          * WCONTINUED and WSTOPPED.
 1245          */
 1246 loop:
 1247         nfound = 0;
 1248         sx_slock(&proctree_lock);
 1249         LIST_FOREACH(p, &q->p_children, p_sibling) {
 1250                 PROC_LOCK(p);
 1251                 if (pid != WAIT_ANY &&
 1252                     p->p_pid != pid && p->p_pgid != -pid) {
 1253                         PROC_UNLOCK(p);
 1254                         DPRINTF(("pid %d pgid %d != %d\n", p->p_pid,
 1255                                  p->p_pgid, pid));
 1256                         continue;
 1257                 }
 1258                 if (p_canwait(td, p)) {
 1259                         PROC_UNLOCK(p);
 1260                         continue;
 1261                 }
 1262 
 1263                 nfound++;
 1264 
 1265                 PROC_SLOCK(p);
 1266                 /*
 1267                  * See if we have a zombie.  If so, WNOWAIT should be set,
 1268                  * as otherwise we should have called kern_wait() up above.
 1269                  */
 1270                 if ((p->p_state == PRS_ZOMBIE) && 
 1271                     ((uap->options & (SVR4_WEXITED|SVR4_WTRAPPED)))) {
 1272                         PROC_SUNLOCK(p);
 1273                         KASSERT(uap->options & SVR4_WNOWAIT,
 1274                             ("WNOWAIT is clear"));
 1275 
 1276                         /* Found a zombie, so cache info in local variables. */
 1277                         pid = p->p_pid;
 1278                         status = p->p_xstat;
 1279                         ru = p->p_ru;
 1280                         PROC_SLOCK(p);
 1281                         calcru(p, &ru.ru_utime, &ru.ru_stime);
 1282                         PROC_SUNLOCK(p);
 1283                         PROC_UNLOCK(p);
 1284                         sx_sunlock(&proctree_lock);
 1285 
 1286                         /* Copy the info out to userland. */
 1287                         *retval = 0;
 1288                         DPRINTF(("found %d\n", pid));
 1289                         return (svr4_setinfo(pid, &ru, status, uap->info));
 1290                 }
 1291 
 1292                 /*
 1293                  * See if we have a stopped or continued process.
 1294                  * XXX: This duplicates the same code in kern_wait().
 1295                  */
 1296                 if ((p->p_flag & P_STOPPED_SIG) &&
 1297                     (p->p_suspcount == p->p_numthreads) &&
 1298                     (p->p_flag & P_WAITED) == 0 &&
 1299                     (p->p_flag & P_TRACED || uap->options & SVR4_WSTOPPED)) {
 1300                         PROC_SUNLOCK(p);
 1301                         if (((uap->options & SVR4_WNOWAIT)) == 0)
 1302                                 p->p_flag |= P_WAITED;
 1303                         sx_sunlock(&proctree_lock);
 1304                         pid = p->p_pid;
 1305                         status = W_STOPCODE(p->p_xstat);
 1306                         ru = p->p_ru;
 1307                         PROC_SLOCK(p);
 1308                         calcru(p, &ru.ru_utime, &ru.ru_stime);
 1309                         PROC_SUNLOCK(p);
 1310                         PROC_UNLOCK(p);
 1311 
 1312                         if (((uap->options & SVR4_WNOWAIT)) == 0) {
 1313                                 PROC_LOCK(q);
 1314                                 sigqueue_take(p->p_ksi);
 1315                                 PROC_UNLOCK(q);
 1316                         }
 1317 
 1318                         *retval = 0;
 1319                         DPRINTF(("jobcontrol %d\n", pid));
 1320                         return (svr4_setinfo(pid, &ru, status, uap->info));
 1321                 }
 1322                 PROC_SUNLOCK(p);
 1323                 if (uap->options & SVR4_WCONTINUED &&
 1324                     (p->p_flag & P_CONTINUED)) {
 1325                         sx_sunlock(&proctree_lock);
 1326                         if (((uap->options & SVR4_WNOWAIT)) == 0)
 1327                                 p->p_flag &= ~P_CONTINUED;
 1328                         pid = p->p_pid;
 1329                         ru = p->p_ru;
 1330                         status = SIGCONT;
 1331                         PROC_SLOCK(p);
 1332                         calcru(p, &ru.ru_utime, &ru.ru_stime);
 1333                         PROC_SUNLOCK(p);
 1334                         PROC_UNLOCK(p);
 1335 
 1336                         if (((uap->options & SVR4_WNOWAIT)) == 0) {
 1337                                 PROC_LOCK(q);
 1338                                 sigqueue_take(p->p_ksi);
 1339                                 PROC_UNLOCK(q);
 1340                         }
 1341 
 1342                         *retval = 0;
 1343                         DPRINTF(("jobcontrol %d\n", pid));
 1344                         return (svr4_setinfo(pid, &ru, status, uap->info));
 1345                 }
 1346                 PROC_UNLOCK(p);
 1347         }
 1348 
 1349         if (nfound == 0) {
 1350                 sx_sunlock(&proctree_lock);
 1351                 return (ECHILD);
 1352         }
 1353 
 1354         if (uap->options & SVR4_WNOHANG) {
 1355                 sx_sunlock(&proctree_lock);
 1356                 *retval = 0;
 1357                 return (svr4_setinfo(0, NULL, 0, uap->info));
 1358         }
 1359 
 1360         PROC_LOCK(q);
 1361         sx_sunlock(&proctree_lock);
 1362         if (q->p_flag & P_STATCHILD) {
 1363                 q->p_flag &= ~P_STATCHILD;
 1364                 error = 0;
 1365         } else
 1366                 error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "svr4_wait", 0);
 1367         PROC_UNLOCK(q);
 1368         if (error)
 1369                 return error;
 1370         goto loop;
 1371 }
 1372 
 1373 
 1374 static void
 1375 bsd_statfs_to_svr4_statvfs(bfs, sfs)
 1376         const struct statfs *bfs;
 1377         struct svr4_statvfs *sfs;
 1378 {
 1379         sfs->f_bsize = bfs->f_iosize; /* XXX */
 1380         sfs->f_frsize = bfs->f_bsize;
 1381         sfs->f_blocks = bfs->f_blocks;
 1382         sfs->f_bfree = bfs->f_bfree;
 1383         sfs->f_bavail = bfs->f_bavail;
 1384         sfs->f_files = bfs->f_files;
 1385         sfs->f_ffree = bfs->f_ffree;
 1386         sfs->f_favail = bfs->f_ffree;
 1387         sfs->f_fsid = bfs->f_fsid.val[0];
 1388         memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype));
 1389         sfs->f_flag = 0;
 1390         if (bfs->f_flags & MNT_RDONLY)
 1391                 sfs->f_flag |= SVR4_ST_RDONLY;
 1392         if (bfs->f_flags & MNT_NOSUID)
 1393                 sfs->f_flag |= SVR4_ST_NOSUID;
 1394         sfs->f_namemax = MAXNAMLEN;
 1395         memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */
 1396         memset(sfs->f_filler, 0, sizeof(sfs->f_filler));
 1397 }
 1398 
 1399 
 1400 static void
 1401 bsd_statfs_to_svr4_statvfs64(bfs, sfs)
 1402         const struct statfs *bfs;
 1403         struct svr4_statvfs64 *sfs;
 1404 {
 1405         sfs->f_bsize = bfs->f_iosize; /* XXX */
 1406         sfs->f_frsize = bfs->f_bsize;
 1407         sfs->f_blocks = bfs->f_blocks;
 1408         sfs->f_bfree = bfs->f_bfree;
 1409         sfs->f_bavail = bfs->f_bavail;
 1410         sfs->f_files = bfs->f_files;
 1411         sfs->f_ffree = bfs->f_ffree;
 1412         sfs->f_favail = bfs->f_ffree;
 1413         sfs->f_fsid = bfs->f_fsid.val[0];
 1414         memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype));
 1415         sfs->f_flag = 0;
 1416         if (bfs->f_flags & MNT_RDONLY)
 1417                 sfs->f_flag |= SVR4_ST_RDONLY;
 1418         if (bfs->f_flags & MNT_NOSUID)
 1419                 sfs->f_flag |= SVR4_ST_NOSUID;
 1420         sfs->f_namemax = MAXNAMLEN;
 1421         memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */
 1422         memset(sfs->f_filler, 0, sizeof(sfs->f_filler));
 1423 }
 1424 
 1425 
 1426 int
 1427 svr4_sys_statvfs(td, uap)
 1428         struct thread *td;
 1429         struct svr4_sys_statvfs_args *uap;
 1430 {
 1431         struct svr4_statvfs sfs;
 1432         struct statfs bfs;
 1433         char *path;
 1434         int error;
 1435 
 1436         CHECKALTEXIST(td, uap->path, &path);
 1437 
 1438         error = kern_statfs(td, path, UIO_SYSSPACE, &bfs);
 1439         free(path, M_TEMP);
 1440         if (error)
 1441                 return (error);
 1442         bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
 1443         return copyout(&sfs, uap->fs, sizeof(sfs));
 1444 }
 1445 
 1446 
 1447 int
 1448 svr4_sys_fstatvfs(td, uap)
 1449         struct thread *td;
 1450         struct svr4_sys_fstatvfs_args *uap;
 1451 {
 1452         struct svr4_statvfs sfs;
 1453         struct statfs bfs;
 1454         int error;
 1455 
 1456         error = kern_fstatfs(td, uap->fd, &bfs);
 1457         if (error)
 1458                 return (error);
 1459         bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
 1460         return copyout(&sfs, uap->fs, sizeof(sfs));
 1461 }
 1462 
 1463 
 1464 int
 1465 svr4_sys_statvfs64(td, uap)
 1466         struct thread *td;
 1467         struct svr4_sys_statvfs64_args *uap;
 1468 {
 1469         struct svr4_statvfs64 sfs;
 1470         struct statfs bfs;
 1471         char *path;
 1472         int error;
 1473 
 1474         CHECKALTEXIST(td, uap->path, &path);
 1475 
 1476         error = kern_statfs(td, path, UIO_SYSSPACE, &bfs);
 1477         free(path, M_TEMP);
 1478         if (error)
 1479                 return (error);
 1480         bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
 1481         return copyout(&sfs, uap->fs, sizeof(sfs));
 1482 }
 1483 
 1484 
 1485 int
 1486 svr4_sys_fstatvfs64(td, uap) 
 1487         struct thread *td;
 1488         struct svr4_sys_fstatvfs64_args *uap;
 1489 {
 1490         struct svr4_statvfs64 sfs;
 1491         struct statfs bfs;
 1492         int error;
 1493 
 1494         error = kern_fstatfs(td, uap->fd, &bfs);
 1495         if (error)
 1496                 return (error);
 1497         bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
 1498         return copyout(&sfs, uap->fs, sizeof(sfs));
 1499 }
 1500 
 1501 int
 1502 svr4_sys_alarm(td, uap)
 1503         struct thread *td;
 1504         struct svr4_sys_alarm_args *uap;
 1505 {
 1506         struct itimerval itv, oitv;
 1507         int error;
 1508 
 1509         timevalclear(&itv.it_interval);
 1510         itv.it_value.tv_sec = uap->sec;
 1511         itv.it_value.tv_usec = 0;
 1512         error = kern_setitimer(td, ITIMER_REAL, &itv, &oitv);
 1513         if (error)
 1514                 return (error);
 1515         if (oitv.it_value.tv_usec != 0)
 1516                 oitv.it_value.tv_sec++;
 1517         td->td_retval[0] = oitv.it_value.tv_sec;
 1518         return (0);
 1519 }
 1520 
 1521 int
 1522 svr4_sys_gettimeofday(td, uap)
 1523         struct thread *td;
 1524         struct svr4_sys_gettimeofday_args *uap;
 1525 {
 1526         if (uap->tp) {
 1527                 struct timeval atv;
 1528 
 1529                 microtime(&atv);
 1530                 return copyout(&atv, uap->tp, sizeof (atv));
 1531         }
 1532 
 1533         return 0;
 1534 }
 1535 
 1536 int
 1537 svr4_sys_facl(td, uap)
 1538         struct thread *td;
 1539         struct svr4_sys_facl_args *uap;
 1540 {
 1541         int *retval;
 1542 
 1543         retval = td->td_retval;
 1544         *retval = 0;
 1545 
 1546         switch (uap->cmd) {
 1547         case SVR4_SYS_SETACL:
 1548                 /* We don't support acls on any filesystem */
 1549                 return ENOSYS;
 1550 
 1551         case SVR4_SYS_GETACL:
 1552                 return copyout(retval, &uap->num,
 1553                     sizeof(uap->num));
 1554 
 1555         case SVR4_SYS_GETACLCNT:
 1556                 return 0;
 1557 
 1558         default:
 1559                 return EINVAL;
 1560         }
 1561 }
 1562 
 1563 
 1564 int
 1565 svr4_sys_acl(td, uap)
 1566         struct thread *td;
 1567         struct svr4_sys_acl_args *uap;
 1568 {
 1569         /* XXX: for now the same */
 1570         return svr4_sys_facl(td, (struct svr4_sys_facl_args *)uap);
 1571 }
 1572 
 1573 int
 1574 svr4_sys_auditsys(td, uap)
 1575         struct thread *td;
 1576         struct svr4_sys_auditsys_args *uap;
 1577 {
 1578         /*
 1579          * XXX: Big brother is *not* watching.
 1580          */
 1581         return 0;
 1582 }
 1583 
 1584 int
 1585 svr4_sys_memcntl(td, uap)
 1586         struct thread *td;
 1587         struct svr4_sys_memcntl_args *uap;
 1588 {
 1589         switch (uap->cmd) {
 1590         case SVR4_MC_SYNC:
 1591                 {
 1592                         struct msync_args msa;
 1593 
 1594                         msa.addr = uap->addr;
 1595                         msa.len = uap->len;
 1596                         msa.flags = (int)uap->arg;
 1597 
 1598                         return msync(td, &msa);
 1599                 }
 1600         case SVR4_MC_ADVISE:
 1601                 {
 1602                         struct madvise_args maa;
 1603 
 1604                         maa.addr = uap->addr;
 1605                         maa.len = uap->len;
 1606                         maa.behav = (int)uap->arg;
 1607 
 1608                         return madvise(td, &maa);
 1609                 }
 1610         case SVR4_MC_LOCK:
 1611         case SVR4_MC_UNLOCK:
 1612         case SVR4_MC_LOCKAS:
 1613         case SVR4_MC_UNLOCKAS:
 1614                 return EOPNOTSUPP;
 1615         default:
 1616                 return ENOSYS;
 1617         }
 1618 }
 1619 
 1620 
 1621 int
 1622 svr4_sys_nice(td, uap)
 1623         struct thread *td;
 1624         struct svr4_sys_nice_args *uap;
 1625 {
 1626         struct setpriority_args ap;
 1627         int error;
 1628 
 1629         ap.which = PRIO_PROCESS;
 1630         ap.who = 0;
 1631         ap.prio = uap->prio;
 1632 
 1633         if ((error = setpriority(td, &ap)) != 0)
 1634                 return error;
 1635 
 1636         /* the cast is stupid, but the structures are the same */
 1637         if ((error = getpriority(td, (struct getpriority_args *)&ap)) != 0)
 1638                 return error;
 1639 
 1640         return 0;
 1641 }
 1642 
 1643 int
 1644 svr4_sys_resolvepath(td, uap)
 1645         struct thread *td;
 1646         struct svr4_sys_resolvepath_args *uap;
 1647 {
 1648         struct nameidata nd;
 1649         int error, *retval = td->td_retval;
 1650         unsigned int ncopy;
 1651         int vfslocked;
 1652 
 1653         NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME | MPSAFE, UIO_USERSPACE,
 1654             uap->path, td);
 1655 
 1656         if ((error = namei(&nd)) != 0)
 1657                 return error;
 1658         vfslocked = NDHASGIANT(&nd);
 1659 
 1660         ncopy = min(uap->bufsiz, strlen(nd.ni_cnd.cn_pnbuf) + 1);
 1661         if ((error = copyout(nd.ni_cnd.cn_pnbuf, uap->buf, ncopy)) != 0)
 1662                 goto bad;
 1663 
 1664         *retval = ncopy;
 1665 bad:
 1666         NDFREE(&nd, NDF_ONLY_PNBUF);
 1667         vput(nd.ni_vp);
 1668         VFS_UNLOCK_GIANT(vfslocked);
 1669         return error;
 1670 }

Cache object: e3f4d61c36d2bb6b304f87ea98b4628e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.