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

Cache object: 5b77c08a66ba2eb54972e493b5183368


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