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_32/svr4_32_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_32_fcntl.c,v 1.14 2006/07/23 22:06:10 ad 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_32_fcntl.c,v 1.14 2006/07/23 22:06:10 ad 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_32/svr4_32_types.h>
   60 #include <compat/svr4_32/svr4_32_signal.h>
   61 #include <compat/svr4_32/svr4_32_ucontext.h>
   62 #include <compat/svr4_32/svr4_32_lwp.h>
   63 #include <compat/svr4_32/svr4_32_syscallargs.h>
   64 #include <compat/svr4_32/svr4_32_util.h>
   65 #include <compat/svr4_32/svr4_32_fcntl.h>
   66 
   67 static u_long svr4_32_to_bsd_cmd __P((u_long));
   68 static int svr4_32_to_bsd_flags __P((int));
   69 static int bsd_to_svr4_32_flags __P((int));
   70 static void bsd_to_svr4_32_flock __P((struct flock *, struct svr4_32_flock *));
   71 static void svr4_32_to_bsd_flock __P((struct svr4_32_flock *, struct flock *));
   72 static void bsd_to_svr4_32_flock64 __P((struct flock *, struct svr4_32_flock64 *));
   73 static void svr4_32_to_bsd_flock64 __P((struct svr4_32_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_32_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_32_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_32_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_32_flock(iflp, oflp)
  152         struct flock            *iflp;
  153         struct svr4_32_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_32_off_t) iflp->l_start;
  172         oflp->l_len = (svr4_32_off_t) iflp->l_len;
  173         oflp->l_sysid = 0;
  174         oflp->l_pid = (svr4_32_pid_t) iflp->l_pid;
  175 }
  176 
  177 
  178 static void
  179 svr4_32_to_bsd_flock(iflp, oflp)
  180         struct svr4_32_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_32_flock64(iflp, oflp)
  207         struct flock            *iflp;
  208         struct svr4_32_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_32_off64_t) iflp->l_start;
  227         oflp->l_len = (svr4_32_off64_t) iflp->l_len;
  228         oflp->l_sysid = 0;
  229         oflp->l_pid = (svr4_32_pid_t) iflp->l_pid;
  230 }
  231 
  232 
  233 static void
  234 svr4_32_to_bsd_flock64(iflp, oflp)
  235         struct svr4_32_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(l, fd, retval)
  263         struct lwp *l;
  264         int fd;
  265         register_t *retval;
  266 {
  267         struct filedesc *fdp = l->l_proc->p_fd;
  268         struct file *fp;
  269         struct vnode *vp;
  270         struct mount *mp;
  271         struct vattr vattr;
  272         int error;
  273 
  274         if ((fp = fd_getfile(fdp, fd)) == NULL)
  275                 return EBADF;
  276 
  277         if (fp->f_type != DTYPE_VNODE)
  278                 return EINVAL;
  279 
  280         vp = (struct vnode *) fp->f_data;
  281 
  282         if (vp->v_type != VCHR && vp->v_type != VBLK) {
  283                 error = EINVAL;
  284                 goto out;
  285         }
  286 
  287         if ((error = VOP_GETATTR(vp, &vattr, l->l_cred, l)) != 0)
  288                 goto out;
  289 
  290         if (kauth_cred_geteuid(l->l_cred) != vattr.va_uid &&
  291             (error = kauth_authorize_generic(l->l_cred,
  292             KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
  293                 goto out;
  294 
  295         if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
  296                 goto out;
  297         if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
  298                 VOP_REVOKE(vp, REVOKEALL);
  299         vn_finished_write(mp, 0);
  300 out:
  301         vrele(vp);
  302         return error;
  303 }
  304 
  305 
  306 static int
  307 fd_truncate(l, fd, flp, retval)
  308         struct lwp *l;
  309         int fd;
  310         struct flock *flp;
  311         register_t *retval;
  312 {
  313         struct filedesc *fdp = l->l_proc->p_fd;
  314         struct file *fp;
  315         off_t start, length;
  316         struct vnode *vp;
  317         struct vattr vattr;
  318         int error;
  319         struct sys_ftruncate_args ft;
  320 
  321         /*
  322          * We only support truncating the file.
  323          */
  324         if ((fp = fd_getfile(fdp, fd)) == NULL)
  325                 return EBADF;
  326 
  327         vp = (struct vnode *)fp->f_data;
  328         if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
  329                 return ESPIPE;
  330 
  331         if ((error = VOP_GETATTR(vp, &vattr, l->l_cred, l)) != 0)
  332                 return error;
  333 
  334         length = vattr.va_size;
  335 
  336         switch (flp->l_whence) {
  337         case SEEK_CUR:
  338                 start = fp->f_offset + flp->l_start;
  339                 break;
  340 
  341         case SEEK_END:
  342                 start = flp->l_start + length;
  343                 break;
  344 
  345         case SEEK_SET:
  346                 start = flp->l_start;
  347                 break;
  348 
  349         default:
  350                 return EINVAL;
  351         }
  352 
  353         if (start + flp->l_len < length) {
  354                 /* We don't support free'ing in the middle of the file */
  355                 return EINVAL;
  356         }
  357 
  358         SCARG(&ft, fd) = fd;
  359         SCARG(&ft, length) = start;
  360 
  361         return sys_ftruncate(l, &ft, retval);
  362 }
  363 
  364 
  365 int
  366 svr4_32_sys_open(l, v, retval)
  367         struct lwp *l;
  368         void *v;
  369         register_t *retval;
  370 {
  371         struct svr4_32_sys_open_args    *uap = v;
  372         struct proc *p = l->l_proc;
  373         int                     error;
  374         struct sys_open_args    cup;
  375 
  376         caddr_t sg = stackgap_init(p, 0);
  377 
  378         SCARG(&cup, flags) = svr4_32_to_bsd_flags(SCARG(uap, flags));
  379 
  380         SCARG(&cup, path) = (char *)(u_long)SCARG(uap, path);
  381         if (SCARG(&cup, flags) & O_CREAT)
  382                 CHECK_ALT_CREAT(l, &sg, SCARG(&cup, path));
  383         else
  384                 CHECK_ALT_EXIST(l, &sg, SCARG(&cup, path));
  385 
  386         SCARG(&cup, mode) = SCARG(uap, mode);
  387         error = sys_open(l, &cup, retval);
  388 
  389         if (error)
  390                 return error;
  391 
  392         if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
  393             !(p->p_flag & P_CONTROLT)) {
  394                 struct filedesc *fdp = p->p_fd;
  395                 struct file     *fp;
  396 
  397                 fp = fd_getfile(fdp, *retval);
  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_32_sys_open64(l, v, retval)
  409         struct lwp *l;
  410         void *v;
  411         register_t *retval;
  412 {
  413         return svr4_32_sys_open(l, v, retval);
  414 }
  415 
  416 
  417 int
  418 svr4_32_sys_creat(l, v, retval)
  419         struct lwp *l;
  420         void *v;
  421         register_t *retval;
  422 {
  423         struct svr4_32_sys_creat_args *uap = v;
  424         struct proc *p = l->l_proc;
  425         struct sys_open_args cup;
  426 
  427         caddr_t sg = stackgap_init(p, 0);
  428 
  429         SCARG(&cup, path) = (char *)(u_long)SCARG(uap, path);
  430         CHECK_ALT_EXIST(l, &sg, SCARG(&cup, path));
  431         SCARG(&cup, mode) = SCARG(uap, mode);
  432         SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
  433 
  434         return sys_open(l, &cup, retval);
  435 }
  436 
  437 
  438 int
  439 svr4_32_sys_creat64(l, v, retval)
  440         struct lwp *l;
  441         void *v;
  442         register_t *retval;
  443 {
  444         return svr4_32_sys_creat(l, v, retval);
  445 }
  446 
  447 
  448 int
  449 svr4_32_sys_llseek(l, v, retval)
  450         struct lwp *l;
  451         void *v;
  452         register_t *retval;
  453 {
  454         struct svr4_32_sys_llseek_args *uap = v;
  455         struct sys_lseek_args ap;
  456 
  457         SCARG(&ap, fd) = SCARG(uap, fd);
  458 
  459 #if BYTE_ORDER == BIG_ENDIAN
  460         SCARG(&ap, offset) = (((long long) SCARG(uap, offset1)) << 32) |
  461                 SCARG(uap, offset2);
  462 #else
  463         SCARG(&ap, offset) = (((long long) SCARG(uap, offset2)) << 32) |
  464                 SCARG(uap, offset1);
  465 #endif
  466         SCARG(&ap, whence) = SCARG(uap, whence);
  467 
  468         return sys_lseek(l, &ap, retval);
  469 }
  470 
  471 int
  472 svr4_32_sys_access(l, v, retval)
  473         struct lwp *l;
  474         void *v;
  475         register_t *retval;
  476 {
  477         struct svr4_32_sys_access_args *uap = v;
  478         struct sys_access_args cup;
  479         struct proc *p = l->l_proc;
  480 
  481         caddr_t sg = stackgap_init(p, 0);
  482 
  483         SCARG(&cup, path) = (char *)(u_long)SCARG(uap, path);
  484         CHECK_ALT_EXIST(l, &sg, SCARG(&cup, path));
  485         SCARG(&cup, flags) = SCARG(uap, flags);
  486 
  487         return sys_access(l, &cup, retval);
  488 }
  489 
  490 
  491 int
  492 svr4_32_sys_pread(l, v, retval)
  493         struct lwp *l;
  494         void *v;
  495         register_t *retval;
  496 {
  497         struct svr4_32_sys_pread_args *uap = v;
  498         struct sys_pread_args pra;
  499 
  500         /*
  501          * Just translate the args structure and call the NetBSD
  502          * pread(2) system call (offset type is 64-bit in NetBSD).
  503          */
  504         SCARG(&pra, fd) = SCARG(uap, fd);
  505         SCARG(&pra, buf) = (void *)(u_long)SCARG(uap, buf);
  506         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  507         SCARG(&pra, offset) = SCARG(uap, off);
  508 
  509         return (sys_pread(l, &pra, retval));
  510 }
  511 
  512 
  513 int
  514 svr4_32_sys_pread64(l, v, retval)
  515         struct lwp *l;
  516         void *v;
  517         register_t *retval;
  518 {
  519 
  520         struct svr4_32_sys_pread64_args *uap = v;
  521         struct sys_pread_args pra;
  522 
  523         /*
  524          * Just translate the args structure and call the NetBSD
  525          * pread(2) system call (offset type is 64-bit in NetBSD).
  526          */
  527         SCARG(&pra, fd) = SCARG(uap, fd);
  528         SCARG(&pra, buf) = (void *)(u_long)SCARG(uap, buf);
  529         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  530         SCARG(&pra, offset) = SCARG(uap, off);
  531 
  532         return (sys_pread(l, &pra, retval));
  533 }
  534 
  535 
  536 int
  537 svr4_32_sys_pwrite(l, v, retval)
  538         struct lwp *l;
  539         void *v;
  540         register_t *retval;
  541 {
  542         struct svr4_32_sys_pwrite_args *uap = v;
  543         struct sys_pwrite_args pwa;
  544 
  545         /*
  546          * Just translate the args structure and call the NetBSD
  547          * pwrite(2) system call (offset type is 64-bit in NetBSD).
  548          */
  549         SCARG(&pwa, fd) = SCARG(uap, fd);
  550         SCARG(&pwa, buf) = (void *)(u_long)SCARG(uap, buf);
  551         SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
  552         SCARG(&pwa, offset) = SCARG(uap, off);
  553 
  554         return (sys_pwrite(l, &pwa, retval));
  555 }
  556 
  557 
  558 int
  559 svr4_32_sys_pwrite64(l, v, retval)
  560         struct lwp *l;
  561         void *v;
  562         register_t *retval;
  563 {
  564         struct svr4_32_sys_pwrite64_args *uap = v;
  565         struct sys_pwrite_args pwa;
  566 
  567         /*
  568          * Just translate the args structure and call the NetBSD
  569          * pwrite(2) system call (offset type is 64-bit in NetBSD).
  570          */
  571         SCARG(&pwa, fd) = SCARG(uap, fd);
  572         SCARG(&pwa, buf) = (void *)(u_long)SCARG(uap, buf);
  573         SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
  574         SCARG(&pwa, offset) = SCARG(uap, off);
  575 
  576         return (sys_pwrite(l, &pwa, retval));
  577 }
  578 
  579 
  580 int
  581 svr4_32_sys_fcntl(l, v, retval)
  582         struct lwp *l;
  583         void *v;
  584         register_t *retval;
  585 {
  586         struct svr4_32_sys_fcntl_args   *uap = v;
  587         struct proc *p = l->l_proc;
  588         int                             error;
  589         struct sys_fcntl_args           fa;
  590 
  591         SCARG(&fa, fd) = SCARG(uap, fd);
  592         SCARG(&fa, cmd) = svr4_32_to_bsd_cmd(SCARG(uap, cmd));
  593 
  594         switch (SCARG(&fa, cmd)) {
  595         case F_DUPFD:
  596         case F_GETFD:
  597         case F_SETFD:
  598                 SCARG(&fa, arg) = (char *)(u_long)SCARG(uap, arg);
  599                 return sys_fcntl(l, &fa, retval);
  600 
  601         case F_GETFL:
  602                 SCARG(&fa, arg) = (char *)(u_long)SCARG(uap, arg);
  603                 error = sys_fcntl(l, &fa, retval);
  604                 if (error)
  605                         return error;
  606                 *retval = bsd_to_svr4_32_flags(*retval);
  607                 return error;
  608 
  609         case F_SETFL:
  610                 {
  611                         /*
  612                          * we must save the O_ASYNC flag, as that is
  613                          * handled by ioctl(_, I_SETSIG, _) emulation.
  614                          */
  615                         register_t flags;
  616                         int cmd;
  617 
  618                         cmd = SCARG(&fa, cmd); /* save it for a while */
  619 
  620                         SCARG(&fa, cmd) = F_GETFL;
  621                         if ((error = sys_fcntl(l, &fa, &flags)) != 0)
  622                                 return error;
  623                         flags &= O_ASYNC;
  624                         flags |= svr4_32_to_bsd_flags((u_long) SCARG(uap, arg));
  625                         SCARG(&fa, cmd) = cmd;
  626                         SCARG(&fa, arg) = (void *) flags;
  627                         return sys_fcntl(l, &fa, retval);
  628                 }
  629 
  630         case F_GETLK:
  631         case F_SETLK:
  632         case F_SETLKW:
  633                 {
  634                         struct svr4_32_flock     ifl;
  635                         struct flock            *flp, fl;
  636                         caddr_t sg = stackgap_init(p, 0);
  637 
  638                         flp = stackgap_alloc(p, &sg, sizeof(struct flock));
  639                         SCARG(&fa, arg) = (void *) flp;
  640 
  641                         error = copyin((char *)(u_long)SCARG(uap, arg),
  642                                        &ifl, sizeof ifl);
  643                         if (error)
  644                                 return error;
  645 
  646                         svr4_32_to_bsd_flock(&ifl, &fl);
  647 
  648                         error = copyout(&fl, flp, sizeof fl);
  649                         if (error)
  650                                 return error;
  651 
  652                         error = sys_fcntl(l, &fa, retval);
  653                         if (error || SCARG(&fa, cmd) != F_GETLK)
  654                                 return error;
  655 
  656                         error = copyin(flp, &fl, sizeof fl);
  657                         if (error)
  658                                 return error;
  659 
  660                         bsd_to_svr4_32_flock(&fl, &ifl);
  661 
  662                         return copyout(&ifl, (char *)(u_long)SCARG(uap, arg),
  663                                        sizeof ifl);
  664                 }
  665         case -1:
  666                 switch (SCARG(uap, cmd)) {
  667                 case SVR4_F_DUP2FD:
  668                         {
  669                                 struct sys_dup2_args du;
  670 
  671                                 SCARG(&du, from) = SCARG(uap, fd);
  672                                 SCARG(&du, to) = (int)(u_long)SCARG(uap, arg);
  673                                 error = sys_dup2(l, &du, retval);
  674                                 if (error)
  675                                         return error;
  676                                 *retval = SCARG(&du, to);
  677                                 return 0;
  678                         }
  679 
  680                 case SVR4_F_FREESP:
  681                         {
  682                                 struct svr4_32_flock     ifl;
  683                                 struct flock             fl;
  684 
  685                                 error = copyin((char *)(u_long)SCARG(uap, arg),
  686                                                &ifl, sizeof ifl);
  687                                 if (error)
  688                                         return error;
  689                                 svr4_32_to_bsd_flock(&ifl, &fl);
  690                                 return fd_truncate(l, SCARG(uap, fd), &fl,
  691                                     retval);
  692                         }
  693 
  694                 case SVR4_F_GETLK64:
  695                 case SVR4_F_SETLK64:
  696                 case SVR4_F_SETLKW64:
  697                         {
  698                                 struct svr4_32_flock64   ifl;
  699                                 struct flock            *flp, fl;
  700                                 caddr_t sg = stackgap_init(p, 0);
  701 
  702                                 flp = stackgap_alloc(p, &sg, sizeof(struct flock));
  703                                 SCARG(&fa, arg) = (void *) flp;
  704 
  705                                 error = copyin((char *)(u_long)SCARG(uap, arg), &ifl,
  706                                     sizeof ifl);
  707                                 if (error)
  708                                         return error;
  709 
  710                                 svr4_32_to_bsd_flock64(&ifl, &fl);
  711 
  712                                 error = copyout(&fl, flp, sizeof fl);
  713                                 if (error)
  714                                         return error;
  715 
  716                                 error = sys_fcntl(l, &fa, retval);
  717                                 if (error || SCARG(&fa, cmd) != F_GETLK)
  718                                         return error;
  719 
  720                                 error = copyin(flp, &fl, sizeof fl);
  721                                 if (error)
  722                                         return error;
  723 
  724                                 bsd_to_svr4_32_flock64(&fl, &ifl);
  725 
  726                                 return copyout(&ifl, (char *)(u_long)SCARG(uap, arg),
  727                                     sizeof ifl);
  728                         }
  729 
  730                 case SVR4_F_FREESP64:
  731                         {
  732                                 struct svr4_32_flock64   ifl;
  733                                 struct flock             fl;
  734 
  735                                 error = copyin((char *)(u_long)SCARG(uap, arg), &ifl,
  736                                     sizeof ifl);
  737                                 if (error)
  738                                         return error;
  739                                 svr4_32_to_bsd_flock64(&ifl, &fl);
  740                                 return fd_truncate(l, SCARG(uap, fd), &fl,
  741                                     retval);
  742                         }
  743 
  744                 case SVR4_F_REVOKE:
  745                         return fd_revoke(l, SCARG(uap, fd), retval);
  746 
  747                 default:
  748                         return ENOSYS;
  749                 }
  750 
  751         default:
  752                 return ENOSYS;
  753         }
  754 }

Cache object: 66c5a46af8aef1e3bce1d1e157550e98


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