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_fcntl.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 /*      $NetBSD: svr4_fcntl.c,v 1.52 2006/11/16 01:32:44 christos Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 1994, 1997 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: svr4_fcntl.c,v 1.52 2006/11/16 01:32:44 christos Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/namei.h>
   45 #include <sys/proc.h>
   46 #include <sys/file.h>
   47 #include <sys/stat.h>
   48 #include <sys/filedesc.h>
   49 #include <sys/ioctl.h>
   50 #include <sys/kernel.h>
   51 #include <sys/mount.h>
   52 #include <sys/malloc.h>
   53 #include <sys/vnode.h>
   54 #include <sys/kauth.h>
   55 
   56 #include <sys/sa.h>
   57 #include <sys/syscallargs.h>
   58 
   59 #include <compat/svr4/svr4_types.h>
   60 #include <compat/svr4/svr4_signal.h>
   61 #include <compat/svr4/svr4_ucontext.h>
   62 #include <compat/svr4/svr4_lwp.h>
   63 #include <compat/svr4/svr4_syscallargs.h>
   64 #include <compat/svr4/svr4_util.h>
   65 #include <compat/svr4/svr4_fcntl.h>
   66 
   67 static u_long svr4_to_bsd_cmd __P((u_long));
   68 static int svr4_to_bsd_flags __P((int));
   69 static int bsd_to_svr4_flags __P((int));
   70 static void bsd_to_svr4_flock __P((struct flock *, struct svr4_flock *));
   71 static void svr4_to_bsd_flock __P((struct svr4_flock *, struct flock *));
   72 static void bsd_to_svr4_flock64 __P((struct flock *, struct svr4_flock64 *));
   73 static void svr4_to_bsd_flock64 __P((struct svr4_flock64 *, struct flock *));
   74 static int fd_revoke __P((struct lwp *, int, register_t *));
   75 static int fd_truncate __P((struct lwp *, int, struct flock *, register_t *));
   76 
   77 static u_long
   78 svr4_to_bsd_cmd(cmd)
   79         u_long  cmd;
   80 {
   81         switch (cmd) {
   82         case SVR4_F_DUPFD:
   83                 return F_DUPFD;
   84         case SVR4_F_GETFD:
   85                 return F_GETFD;
   86         case SVR4_F_SETFD:
   87                 return F_SETFD;
   88         case SVR4_F_GETFL:
   89                 return F_GETFL;
   90         case SVR4_F_SETFL:
   91                 return F_SETFL;
   92         case SVR4_F_GETLK:
   93                 return F_GETLK;
   94         case SVR4_F_SETLK:
   95                 return F_SETLK;
   96         case SVR4_F_SETLKW:
   97                 return F_SETLKW;
   98         default:
   99                 return -1;
  100         }
  101 }
  102 
  103 
  104 static int
  105 svr4_to_bsd_flags(l)
  106         int     l;
  107 {
  108         int     r = 0;
  109         r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
  110         r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
  111         r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
  112         r |= (l & SVR4_O_NDELAY) ? O_NDELAY : 0;
  113         r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
  114         r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
  115         r |= (l & SVR4_O_RSYNC) ? O_RSYNC : 0;
  116         r |= (l & SVR4_O_DSYNC) ? O_DSYNC : 0;
  117         r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
  118         r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
  119         r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
  120         r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
  121         r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
  122         r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
  123         return r;
  124 }
  125 
  126 
  127 static int
  128 bsd_to_svr4_flags(l)
  129         int     l;
  130 {
  131         int     r = 0;
  132         r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
  133         r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
  134         r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
  135         r |= (l & O_NDELAY) ? SVR4_O_NDELAY : 0;
  136         r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
  137         r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
  138         r |= (l & O_RSYNC) ? SVR4_O_RSYNC : 0;
  139         r |= (l & O_DSYNC) ? SVR4_O_DSYNC : 0;
  140         r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
  141         r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
  142         r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
  143         r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
  144         r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
  145         r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
  146         return r;
  147 }
  148 
  149 
  150 static void
  151 bsd_to_svr4_flock(iflp, oflp)
  152         struct flock            *iflp;
  153         struct svr4_flock       *oflp;
  154 {
  155         switch (iflp->l_type) {
  156         case F_RDLCK:
  157                 oflp->l_type = SVR4_F_RDLCK;
  158                 break;
  159         case F_WRLCK:
  160                 oflp->l_type = SVR4_F_WRLCK;
  161                 break;
  162         case F_UNLCK:
  163                 oflp->l_type = SVR4_F_UNLCK;
  164                 break;
  165         default:
  166                 oflp->l_type = -1;
  167                 break;
  168         }
  169 
  170         oflp->l_whence = (short) iflp->l_whence;
  171         oflp->l_start = (svr4_off_t) iflp->l_start;
  172         oflp->l_len = (svr4_off_t) iflp->l_len;
  173         oflp->l_sysid = 0;
  174         oflp->l_pid = (svr4_pid_t) iflp->l_pid;
  175 }
  176 
  177 
  178 static void
  179 svr4_to_bsd_flock(iflp, oflp)
  180         struct svr4_flock       *iflp;
  181         struct flock            *oflp;
  182 {
  183         switch (iflp->l_type) {
  184         case SVR4_F_RDLCK:
  185                 oflp->l_type = F_RDLCK;
  186                 break;
  187         case SVR4_F_WRLCK:
  188                 oflp->l_type = F_WRLCK;
  189                 break;
  190         case SVR4_F_UNLCK:
  191                 oflp->l_type = F_UNLCK;
  192                 break;
  193         default:
  194                 oflp->l_type = -1;
  195                 break;
  196         }
  197 
  198         oflp->l_whence = iflp->l_whence;
  199         oflp->l_start = (off_t) iflp->l_start;
  200         oflp->l_len = (off_t) iflp->l_len;
  201         oflp->l_pid = (pid_t) iflp->l_pid;
  202 
  203 }
  204 
  205 static void
  206 bsd_to_svr4_flock64(iflp, oflp)
  207         struct flock            *iflp;
  208         struct svr4_flock64     *oflp;
  209 {
  210         switch (iflp->l_type) {
  211         case F_RDLCK:
  212                 oflp->l_type = SVR4_F_RDLCK;
  213                 break;
  214         case F_WRLCK:
  215                 oflp->l_type = SVR4_F_WRLCK;
  216                 break;
  217         case F_UNLCK:
  218                 oflp->l_type = SVR4_F_UNLCK;
  219                 break;
  220         default:
  221                 oflp->l_type = -1;
  222                 break;
  223         }
  224 
  225         oflp->l_whence = (short) iflp->l_whence;
  226         oflp->l_start = (svr4_off64_t) iflp->l_start;
  227         oflp->l_len = (svr4_off64_t) iflp->l_len;
  228         oflp->l_sysid = 0;
  229         oflp->l_pid = (svr4_pid_t) iflp->l_pid;
  230 }
  231 
  232 
  233 static void
  234 svr4_to_bsd_flock64(iflp, oflp)
  235         struct svr4_flock64     *iflp;
  236         struct flock            *oflp;
  237 {
  238         switch (iflp->l_type) {
  239         case SVR4_F_RDLCK:
  240                 oflp->l_type = F_RDLCK;
  241                 break;
  242         case SVR4_F_WRLCK:
  243                 oflp->l_type = F_WRLCK;
  244                 break;
  245         case SVR4_F_UNLCK:
  246                 oflp->l_type = F_UNLCK;
  247                 break;
  248         default:
  249                 oflp->l_type = -1;
  250                 break;
  251         }
  252 
  253         oflp->l_whence = iflp->l_whence;
  254         oflp->l_start = (off_t) iflp->l_start;
  255         oflp->l_len = (off_t) iflp->l_len;
  256         oflp->l_pid = (pid_t) iflp->l_pid;
  257 
  258 }
  259 
  260 
  261 static int
  262 fd_revoke(struct lwp *l, int fd, register_t *retval)
  263 {
  264         struct filedesc *fdp = l->l_proc->p_fd;
  265         struct file *fp;
  266         struct vnode *vp;
  267         struct mount *mp;
  268         struct vattr vattr;
  269         int error;
  270 
  271         if ((fp = fd_getfile(fdp, fd)) == NULL)
  272                 return EBADF;
  273 
  274         simple_unlock(&fp->f_slock);
  275         if (fp->f_type != DTYPE_VNODE)
  276                 return EINVAL;
  277 
  278         vp = (struct vnode *) fp->f_data;
  279 
  280         if (vp->v_type != VCHR && vp->v_type != VBLK) {
  281                 error = EINVAL;
  282                 goto out;
  283         }
  284 
  285         if ((error = VOP_GETATTR(vp, &vattr, l->l_cred, l)) != 0)
  286                 goto out;
  287 
  288         if (kauth_cred_geteuid(l->l_cred) != vattr.va_uid &&
  289             (error = kauth_authorize_generic(l->l_cred,
  290             KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
  291                 goto out;
  292 
  293         if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
  294                 goto out;
  295         if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
  296                 VOP_REVOKE(vp, REVOKEALL);
  297         vn_finished_write(mp, 0);
  298 out:
  299         vrele(vp);
  300         return error;
  301 }
  302 
  303 
  304 static int
  305 fd_truncate(l, fd, flp, retval)
  306         struct lwp *l;
  307         int fd;
  308         struct flock *flp;
  309         register_t *retval;
  310 {
  311         struct filedesc *fdp = l->l_proc->p_fd;
  312         struct file *fp;
  313         off_t start, length;
  314         struct vnode *vp;
  315         struct vattr vattr;
  316         int error;
  317         struct sys_ftruncate_args ft;
  318 
  319         /*
  320          * We only support truncating the file.
  321          */
  322         if ((fp = fd_getfile(fdp, fd)) == NULL)
  323                 return EBADF;
  324 
  325         simple_unlock(&fp->f_slock);
  326         vp = (struct vnode *)fp->f_data;
  327         if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
  328                 return ESPIPE;
  329 
  330         if ((error = VOP_GETATTR(vp, &vattr, l->l_cred, l)) != 0)
  331                 return error;
  332 
  333         length = vattr.va_size;
  334 
  335         switch (flp->l_whence) {
  336         case SEEK_CUR:
  337                 start = fp->f_offset + flp->l_start;
  338                 break;
  339 
  340         case SEEK_END:
  341                 start = flp->l_start + length;
  342                 break;
  343 
  344         case SEEK_SET:
  345                 start = flp->l_start;
  346                 break;
  347 
  348         default:
  349                 return EINVAL;
  350         }
  351 
  352         if (start + flp->l_len < length) {
  353                 /* We don't support free'ing in the middle of the file */
  354                 return EINVAL;
  355         }
  356 
  357         SCARG(&ft, fd) = fd;
  358         SCARG(&ft, length) = start;
  359 
  360         return sys_ftruncate(l, &ft, retval);
  361 }
  362 
  363 
  364 int
  365 svr4_sys_open(l, v, retval)
  366         struct lwp *l;
  367         void *v;
  368         register_t *retval;
  369 {
  370         struct svr4_sys_open_args       *uap = v;
  371         struct proc *p = l->l_proc;
  372         int                     error;
  373         struct sys_open_args    cup;
  374 
  375         caddr_t sg = stackgap_init(p, 0);
  376 
  377         SCARG(&cup, flags) = svr4_to_bsd_flags(SCARG(uap, flags));
  378 
  379         if (SCARG(&cup, flags) & O_CREAT)
  380                 CHECK_ALT_CREAT(l, &sg, SCARG(uap, path));
  381         else
  382                 CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
  383 
  384         SCARG(&cup, path) = SCARG(uap, path);
  385         SCARG(&cup, mode) = SCARG(uap, mode);
  386         error = sys_open(l, &cup, retval);
  387 
  388         if (error)
  389                 return error;
  390 
  391         if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
  392             !(p->p_flag & P_CONTROLT)) {
  393                 struct filedesc *fdp = p->p_fd;
  394                 struct file     *fp;
  395 
  396                 fp = fd_getfile(fdp, *retval);
  397                 simple_unlock(&fp->f_slock);
  398 
  399                 /* ignore any error, just give it a try */
  400                 if (fp != NULL && fp->f_type == DTYPE_VNODE)
  401                         (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, l);
  402         }
  403         return 0;
  404 }
  405 
  406 
  407 int
  408 svr4_sys_open64(l, v, retval)
  409         struct lwp *l;
  410         void *v;
  411         register_t *retval;
  412 {
  413         return svr4_sys_open(l, v, retval);
  414 }
  415 
  416 
  417 int
  418 svr4_sys_creat(l, v, retval)
  419         struct lwp *l;
  420         void *v;
  421         register_t *retval;
  422 {
  423         struct svr4_sys_creat_args *uap = v;
  424         struct sys_open_args cup;
  425 
  426         caddr_t sg = stackgap_init(l->l_proc, 0);
  427         CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
  428 
  429         SCARG(&cup, path) = SCARG(uap, path);
  430         SCARG(&cup, mode) = SCARG(uap, mode);
  431         SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
  432 
  433         return sys_open(l, &cup, retval);
  434 }
  435 
  436 
  437 int
  438 svr4_sys_creat64(l, v, retval)
  439         struct lwp *l;
  440         void *v;
  441         register_t *retval;
  442 {
  443         return svr4_sys_creat(l, v, retval);
  444 }
  445 
  446 
  447 int
  448 svr4_sys_llseek(l, v, retval)
  449         struct lwp *l;
  450         void *v;
  451         register_t *retval;
  452 {
  453         struct svr4_sys_llseek_args *uap = v;
  454         struct sys_lseek_args ap;
  455 
  456         SCARG(&ap, fd) = SCARG(uap, fd);
  457 
  458 #if BYTE_ORDER == BIG_ENDIAN
  459         SCARG(&ap, offset) = (((long long) SCARG(uap, offset1)) << 32) |
  460                 SCARG(uap, offset2);
  461 #else
  462         SCARG(&ap, offset) = (((long long) SCARG(uap, offset2)) << 32) |
  463                 SCARG(uap, offset1);
  464 #endif
  465         SCARG(&ap, whence) = SCARG(uap, whence);
  466 
  467         return sys_lseek(l, &ap, retval);
  468 }
  469 
  470 int
  471 svr4_sys_access(l, v, retval)
  472         struct lwp *l;
  473         void *v;
  474         register_t *retval;
  475 {
  476         struct svr4_sys_access_args *uap = v;
  477         struct sys_access_args cup;
  478 
  479         caddr_t sg = stackgap_init(l->l_proc, 0);
  480         CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
  481 
  482         SCARG(&cup, path) = SCARG(uap, path);
  483         SCARG(&cup, flags) = SCARG(uap, flags);
  484 
  485         return sys_access(l, &cup, retval);
  486 }
  487 
  488 
  489 int
  490 svr4_sys_pread(l, v, retval)
  491         struct lwp *l;
  492         void *v;
  493         register_t *retval;
  494 {
  495         struct svr4_sys_pread_args *uap = v;
  496         struct sys_pread_args pra;
  497 
  498         /*
  499          * Just translate the args structure and call the NetBSD
  500          * pread(2) system call (offset type is 64-bit in NetBSD).
  501          */
  502         SCARG(&pra, fd) = SCARG(uap, fd);
  503         SCARG(&pra, buf) = SCARG(uap, buf);
  504         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  505         SCARG(&pra, offset) = SCARG(uap, off);
  506 
  507         return (sys_pread(l, &pra, retval));
  508 }
  509 
  510 
  511 int
  512 svr4_sys_pread64(l, v, retval)
  513         struct lwp *l;
  514         void *v;
  515         register_t *retval;
  516 {
  517 
  518         struct svr4_sys_pread64_args *uap = v;
  519         struct sys_pread_args pra;
  520 
  521         /*
  522          * Just translate the args structure and call the NetBSD
  523          * pread(2) system call (offset type is 64-bit in NetBSD).
  524          */
  525         SCARG(&pra, fd) = SCARG(uap, fd);
  526         SCARG(&pra, buf) = SCARG(uap, buf);
  527         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  528         SCARG(&pra, offset) = SCARG(uap, off);
  529 
  530         return (sys_pread(l, &pra, retval));
  531 }
  532 
  533 
  534 int
  535 svr4_sys_pwrite(l, v, retval)
  536         struct lwp *l;
  537         void *v;
  538         register_t *retval;
  539 {
  540         struct svr4_sys_pwrite_args *uap = v;
  541         struct sys_pwrite_args pwa;
  542 
  543         /*
  544          * Just translate the args structure and call the NetBSD
  545          * pwrite(2) system call (offset type is 64-bit in NetBSD).
  546          */
  547         SCARG(&pwa, fd) = SCARG(uap, fd);
  548         SCARG(&pwa, buf) = SCARG(uap, buf);
  549         SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
  550         SCARG(&pwa, offset) = SCARG(uap, off);
  551 
  552         return (sys_pwrite(l, &pwa, retval));
  553 }
  554 
  555 
  556 int
  557 svr4_sys_pwrite64(l, v, retval)
  558         struct lwp *l;
  559         void *v;
  560         register_t *retval;
  561 {
  562         struct svr4_sys_pwrite64_args *uap = v;
  563         struct sys_pwrite_args pwa;
  564 
  565         /*
  566          * Just translate the args structure and call the NetBSD
  567          * pwrite(2) system call (offset type is 64-bit in NetBSD).
  568          */
  569         SCARG(&pwa, fd) = SCARG(uap, fd);
  570         SCARG(&pwa, buf) = SCARG(uap, buf);
  571         SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
  572         SCARG(&pwa, offset) = SCARG(uap, off);
  573 
  574         return (sys_pwrite(l, &pwa, retval));
  575 }
  576 
  577 
  578 int
  579 svr4_sys_fcntl(l, v, retval)
  580         struct lwp *l;
  581         void *v;
  582         register_t *retval;
  583 {
  584         struct svr4_sys_fcntl_args      *uap = v;
  585         struct proc *p = l->l_proc;
  586         int                             error;
  587         struct sys_fcntl_args           fa;
  588 
  589         SCARG(&fa, fd) = SCARG(uap, fd);
  590         SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd));
  591 
  592         switch (SCARG(&fa, cmd)) {
  593         case F_DUPFD:
  594         case F_GETFD:
  595         case F_SETFD:
  596                 SCARG(&fa, arg) = SCARG(uap, arg);
  597                 return sys_fcntl(l, &fa, retval);
  598 
  599         case F_GETFL:
  600                 SCARG(&fa, arg) = SCARG(uap, arg);
  601                 error = sys_fcntl(l, &fa, retval);
  602                 if (error)
  603                         return error;
  604                 *retval = bsd_to_svr4_flags(*retval);
  605                 return error;
  606 
  607         case F_SETFL:
  608                 {
  609                         /*
  610                          * we must save the O_ASYNC flag, as that is
  611                          * handled by ioctl(_, I_SETSIG, _) emulation.
  612                          */
  613                         register_t flags;
  614                         int cmd;
  615 
  616                         cmd = SCARG(&fa, cmd); /* save it for a while */
  617 
  618                         SCARG(&fa, cmd) = F_GETFL;
  619                         if ((error = sys_fcntl(l, &fa, &flags)) != 0)
  620                                 return error;
  621                         flags &= O_ASYNC;
  622                         flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg));
  623                         SCARG(&fa, cmd) = cmd;
  624                         SCARG(&fa, arg) = (void *) flags;
  625                         return sys_fcntl(l, &fa, retval);
  626                 }
  627 
  628         case F_GETLK:
  629         case F_SETLK:
  630         case F_SETLKW:
  631                 {
  632                         struct svr4_flock        ifl;
  633                         struct flock            *flp, fl;
  634                         caddr_t sg = stackgap_init(p, 0);
  635 
  636                         flp = stackgap_alloc(p, &sg, sizeof(struct flock));
  637                         SCARG(&fa, arg) = (void *) flp;
  638 
  639                         error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
  640                         if (error)
  641                                 return error;
  642 
  643                         svr4_to_bsd_flock(&ifl, &fl);
  644 
  645                         error = copyout(&fl, flp, sizeof fl);
  646                         if (error)
  647                                 return error;
  648 
  649                         error = sys_fcntl(l, &fa, retval);
  650                         if (error || SCARG(&fa, cmd) != F_GETLK)
  651                                 return error;
  652 
  653                         error = copyin(flp, &fl, sizeof fl);
  654                         if (error)
  655                                 return error;
  656 
  657                         bsd_to_svr4_flock(&fl, &ifl);
  658 
  659                         return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
  660                 }
  661         case -1:
  662                 switch (SCARG(uap, cmd)) {
  663                 case SVR4_F_DUP2FD:
  664                         {
  665                                 struct sys_dup2_args du;
  666 
  667                                 SCARG(&du, from) = SCARG(uap, fd);
  668                                 SCARG(&du, to) = (int)(u_long)SCARG(uap, arg);
  669                                 error = sys_dup2(l, &du, retval);
  670                                 if (error)
  671                                         return error;
  672                                 *retval = SCARG(&du, to);
  673                                 return 0;
  674                         }
  675 
  676                 case SVR4_F_FREESP:
  677                         {
  678                                 struct svr4_flock        ifl;
  679                                 struct flock             fl;
  680 
  681                                 error = copyin(SCARG(uap, arg), &ifl,
  682                                     sizeof ifl);
  683                                 if (error)
  684                                         return error;
  685                                 svr4_to_bsd_flock(&ifl, &fl);
  686                                 return fd_truncate(l, SCARG(uap, fd), &fl,
  687                                     retval);
  688                         }
  689 
  690                 case SVR4_F_GETLK64:
  691                 case SVR4_F_SETLK64:
  692                 case SVR4_F_SETLKW64:
  693                         {
  694                                 struct svr4_flock64      ifl;
  695                                 struct flock            *flp, fl;
  696                                 caddr_t sg = stackgap_init(p, 0);
  697 
  698                                 flp = stackgap_alloc(p, &sg,
  699                                     sizeof(struct flock));
  700                                 SCARG(&fa, arg) = (void *) flp;
  701 
  702                                 error = copyin(SCARG(uap, arg), &ifl,
  703                                     sizeof ifl);
  704                                 if (error)
  705                                         return error;
  706 
  707                                 svr4_to_bsd_flock64(&ifl, &fl);
  708 
  709                                 error = copyout(&fl, flp, sizeof fl);
  710                                 if (error)
  711                                         return error;
  712 
  713                                 error = sys_fcntl(l, &fa, retval);
  714                                 if (error || SCARG(&fa, cmd) != F_GETLK)
  715                                         return error;
  716 
  717                                 error = copyin(flp, &fl, sizeof fl);
  718                                 if (error)
  719                                         return error;
  720 
  721                                 bsd_to_svr4_flock64(&fl, &ifl);
  722 
  723                                 return copyout(&ifl, SCARG(uap, arg),
  724                                     sizeof ifl);
  725                         }
  726 
  727                 case SVR4_F_FREESP64:
  728                         {
  729                                 struct svr4_flock64      ifl;
  730                                 struct flock             fl;
  731 
  732                                 error = copyin(SCARG(uap, arg), &ifl,
  733                                     sizeof ifl);
  734                                 if (error)
  735                                         return error;
  736                                 svr4_to_bsd_flock64(&ifl, &fl);
  737                                 return fd_truncate(l, SCARG(uap, fd), &fl,
  738                                     retval);
  739                         }
  740 
  741                 case SVR4_F_REVOKE:
  742                         return fd_revoke(l, SCARG(uap, fd), retval);
  743 
  744                 default:
  745                         return ENOSYS;
  746                 }
  747 
  748         default:
  749                 return ENOSYS;
  750         }
  751 }

Cache object: 9c521414e3a5cf659ecc3d2e06d6641e


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