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/i386/ibcs2/ibcs2_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  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 1995 Scott Bartram
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include "opt_spx_hack.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/capsicum.h>
   38 #include <sys/fcntl.h>
   39 #include <sys/file.h>
   40 #include <sys/filedesc.h>
   41 #include <sys/lock.h>
   42 #include <sys/malloc.h>
   43 #include <sys/mutex.h>
   44 #include <sys/syscallsubr.h>
   45 #include <sys/sysproto.h>
   46 #include <sys/ttycom.h>
   47 
   48 #include <i386/ibcs2/ibcs2_fcntl.h>
   49 #include <i386/ibcs2/ibcs2_signal.h>
   50 #include <i386/ibcs2/ibcs2_proto.h>
   51 #include <i386/ibcs2/ibcs2_util.h>
   52 
   53 static void cvt_iflock2flock(struct ibcs2_flock *, struct flock *);
   54 static void cvt_flock2iflock(struct flock *, struct ibcs2_flock *);
   55 static int  cvt_o_flags(int);
   56 static int  oflags2ioflags(int);
   57 static int  ioflags2oflags(int);
   58 
   59 static int
   60 cvt_o_flags(flags)
   61         int flags;
   62 {
   63         int r = 0;
   64 
   65         /* convert mode into NetBSD mode */
   66         if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
   67         if (flags & IBCS2_O_RDWR)   r |= O_RDWR;
   68         if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK;
   69         if (flags & IBCS2_O_APPEND) r |= O_APPEND;
   70         if (flags & IBCS2_O_SYNC)   r |= O_FSYNC;
   71         if (flags & IBCS2_O_CREAT)  r |= O_CREAT;
   72         if (flags & IBCS2_O_TRUNC)  r |= O_TRUNC /* | O_CREAT ??? */;
   73         if (flags & IBCS2_O_EXCL)   r |= O_EXCL;
   74         if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
   75         if (flags & IBCS2_O_PRIV)   r |= O_EXLOCK;
   76         if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
   77         return r;
   78 }
   79 
   80 static void
   81 cvt_flock2iflock(flp, iflp)
   82         struct flock *flp;
   83         struct ibcs2_flock *iflp;
   84 {
   85         switch (flp->l_type) {
   86         case F_RDLCK:
   87                 iflp->l_type = IBCS2_F_RDLCK;
   88                 break;
   89         case F_WRLCK:
   90                 iflp->l_type = IBCS2_F_WRLCK;
   91                 break;
   92         case F_UNLCK:
   93                 iflp->l_type = IBCS2_F_UNLCK;
   94                 break;
   95         }
   96         iflp->l_whence = (short)flp->l_whence;
   97         iflp->l_start = (ibcs2_off_t)flp->l_start;
   98         iflp->l_len = (ibcs2_off_t)flp->l_len;
   99         iflp->l_sysid = flp->l_sysid;
  100         iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
  101 }
  102 
  103 #ifdef DEBUG_IBCS2
  104 static void
  105 print_flock(struct flock *flp)
  106 {
  107   printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n",
  108          (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid,
  109          flp->l_type, flp->l_whence);
  110 }
  111 #endif
  112 
  113 static void
  114 cvt_iflock2flock(iflp, flp)
  115         struct ibcs2_flock *iflp;
  116         struct flock *flp;
  117 {
  118         flp->l_start = (off_t)iflp->l_start;
  119         flp->l_len = (off_t)iflp->l_len;
  120         flp->l_pid = (pid_t)iflp->l_pid;
  121         switch (iflp->l_type) {
  122         case IBCS2_F_RDLCK:
  123                 flp->l_type = F_RDLCK;
  124                 break;
  125         case IBCS2_F_WRLCK:
  126                 flp->l_type = F_WRLCK;
  127                 break;
  128         case IBCS2_F_UNLCK:
  129                 flp->l_type = F_UNLCK;
  130                 break;
  131         }
  132         flp->l_whence = iflp->l_whence;
  133         flp->l_sysid = iflp->l_sysid;
  134 }
  135 
  136 /* convert iBCS2 mode into NetBSD mode */
  137 static int
  138 ioflags2oflags(flags)
  139         int flags;
  140 {
  141         int r = 0;
  142         
  143         if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
  144         if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
  145         if (flags & IBCS2_O_RDWR) r |= O_RDWR;
  146         if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK;
  147         if (flags & IBCS2_O_APPEND) r |= O_APPEND;
  148         if (flags & IBCS2_O_SYNC) r |= O_FSYNC;
  149         if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK;
  150         if (flags & IBCS2_O_CREAT) r |= O_CREAT;
  151         if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
  152         if (flags & IBCS2_O_EXCL) r |= O_EXCL;
  153         if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
  154         return r;
  155 }
  156 
  157 /* convert NetBSD mode into iBCS2 mode */
  158 static int
  159 oflags2ioflags(flags)
  160         int flags;
  161 {
  162         int r = 0;
  163         
  164         if (flags & O_RDONLY) r |= IBCS2_O_RDONLY;
  165         if (flags & O_WRONLY) r |= IBCS2_O_WRONLY;
  166         if (flags & O_RDWR) r |= IBCS2_O_RDWR;
  167         if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK;
  168         if (flags & O_APPEND) r |= IBCS2_O_APPEND;
  169         if (flags & O_FSYNC) r |= IBCS2_O_SYNC;
  170         if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK;
  171         if (flags & O_CREAT) r |= IBCS2_O_CREAT;
  172         if (flags & O_TRUNC) r |= IBCS2_O_TRUNC;
  173         if (flags & O_EXCL) r |= IBCS2_O_EXCL;
  174         if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY;
  175         return r;
  176 }
  177 
  178 int
  179 ibcs2_open(td, uap)
  180         struct thread *td;
  181         struct ibcs2_open_args *uap;
  182 {
  183         struct proc *p;
  184         char *path;
  185         int flags, noctty, ret;
  186 
  187         p = td->td_proc;
  188         noctty = uap->flags & IBCS2_O_NOCTTY;
  189         flags = cvt_o_flags(uap->flags);
  190         if (uap->flags & O_CREAT)
  191                 CHECKALTCREAT(td, uap->path, &path);
  192         else
  193                 CHECKALTEXIST(td, uap->path, &path);
  194         ret = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, flags, uap->mode);
  195 
  196 #ifdef SPX_HACK
  197         if (ret == ENXIO) {
  198                 if (!strcmp(path, "/compat/ibcs2/dev/spx"))
  199                         ret = spx_open(td);
  200                 free(path, M_TEMP);
  201         } else
  202 #endif /* SPX_HACK */
  203         free(path, M_TEMP);
  204         PROC_LOCK(p);
  205         if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
  206                 cap_rights_t rights;
  207                 struct file *fp;
  208                 int error;
  209 
  210                 error = fget(td, td->td_retval[0],
  211                     cap_rights_init(&rights, CAP_IOCTL), &fp);
  212                 PROC_UNLOCK(p);
  213                 if (error)
  214                         return (EBADF);
  215 
  216                 /* ignore any error, just give it a try */
  217                 if (fp->f_type == DTYPE_VNODE)
  218                         fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred,
  219                             td);
  220                 fdrop(fp, td);
  221         } else
  222                 PROC_UNLOCK(p);
  223         return ret;
  224 }
  225 
  226 int
  227 ibcs2_creat(td, uap)
  228         struct thread *td;  
  229         struct ibcs2_creat_args *uap;
  230 {
  231         char *path;
  232         int error;
  233 
  234         CHECKALTCREAT(td, uap->path, &path);
  235         error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE,
  236             O_WRONLY | O_CREAT | O_TRUNC, uap->mode);
  237         free(path, M_TEMP);
  238         return (error);
  239 }       
  240 
  241 int
  242 ibcs2_access(td, uap)
  243         struct thread *td;
  244         struct ibcs2_access_args *uap;
  245 {
  246         char *path;
  247         int error;
  248 
  249         CHECKALTEXIST(td, uap->path, &path);
  250         error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, uap->amode);
  251         free(path, M_TEMP);
  252         return (error);
  253 }
  254 
  255 int
  256 ibcs2_fcntl(td, uap)
  257         struct thread *td;
  258         struct ibcs2_fcntl_args *uap;
  259 {
  260         intptr_t arg;
  261         int error;
  262         struct flock fl;
  263         struct ibcs2_flock ifl;
  264 
  265         arg = (intptr_t)uap->arg;
  266         switch(uap->cmd) {
  267         case IBCS2_F_DUPFD:
  268                 return (kern_fcntl(td, uap->fd, F_DUPFD, arg));
  269         case IBCS2_F_GETFD:
  270                 return (kern_fcntl(td, uap->fd, F_GETFD, arg));
  271         case IBCS2_F_SETFD:
  272                 return (kern_fcntl(td, uap->fd, F_SETFD, arg));
  273         case IBCS2_F_GETFL:
  274                 error = kern_fcntl(td, uap->fd, F_GETFL, arg);
  275                 if (error)
  276                         return error;
  277                 td->td_retval[0] = oflags2ioflags(td->td_retval[0]);
  278                 return error;
  279         case IBCS2_F_SETFL:
  280                 return (kern_fcntl(td, uap->fd, F_SETFL,
  281                     ioflags2oflags(arg)));
  282 
  283         case IBCS2_F_GETLK:
  284             {
  285                 error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
  286                                ibcs2_flock_len);
  287                 if (error)
  288                         return error;
  289                 cvt_iflock2flock(&ifl, &fl);
  290                 error = kern_fcntl(td, uap->fd, F_GETLK, (intptr_t)&fl);
  291                 if (error)
  292                         return error;
  293                 cvt_flock2iflock(&fl, &ifl);
  294                 return copyout((caddr_t)&ifl, (caddr_t)uap->arg,
  295                                ibcs2_flock_len);
  296             }
  297 
  298         case IBCS2_F_SETLK:
  299             {
  300                 error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
  301                                ibcs2_flock_len);
  302                 if (error)
  303                         return error;
  304                 cvt_iflock2flock(&ifl, &fl);
  305                 return (kern_fcntl(td, uap->fd, F_SETLK, (intptr_t)&fl));
  306             }
  307 
  308         case IBCS2_F_SETLKW:
  309             {
  310                 error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
  311                                ibcs2_flock_len);
  312                 if (error)
  313                         return error;
  314                 cvt_iflock2flock(&ifl, &fl);
  315                 return (kern_fcntl(td, uap->fd, F_SETLKW, (intptr_t)&fl));
  316             }
  317         }
  318         return ENOSYS;
  319 }

Cache object: 2081052dccf201cd85ee677d6ef07aef


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