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

Cache object: ba64da05bedfd27c798f822d7ac31f24


[ 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.