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/linux/common/linux_file.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: linux_file.c,v 1.96 2008/04/28 20:23:43 martin Exp $   */
    2 
    3 /*-
    4  * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Frank van der Linden and Eric Haszlakiewicz.
    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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Functions in multiarch:
   34  *      linux_sys_llseek        : linux_llseek.c
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.96 2008/04/28 20:23:43 martin Exp $");
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/namei.h>
   43 #include <sys/proc.h>
   44 #include <sys/file.h>
   45 #include <sys/stat.h>
   46 #include <sys/filedesc.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/kernel.h>
   49 #include <sys/mount.h>
   50 #include <sys/malloc.h>
   51 #include <sys/namei.h>
   52 #include <sys/vnode.h>
   53 #include <sys/tty.h>
   54 #include <sys/socketvar.h>
   55 #include <sys/conf.h>
   56 #include <sys/pipe.h>
   57 
   58 #include <sys/syscallargs.h>
   59 #include <sys/vfs_syscalls.h>
   60 
   61 #include <compat/linux/common/linux_types.h>
   62 #include <compat/linux/common/linux_signal.h>
   63 #include <compat/linux/common/linux_fcntl.h>
   64 #include <compat/linux/common/linux_util.h>
   65 #include <compat/linux/common/linux_machdep.h>
   66 #include <compat/linux/common/linux_ipc.h>
   67 #include <compat/linux/common/linux_sem.h>
   68 
   69 #include <compat/linux/linux_syscallargs.h>
   70 
   71 static int linux_to_bsd_ioflags(int);
   72 static int bsd_to_linux_ioflags(int);
   73 #ifndef __amd64__
   74 static void bsd_to_linux_stat(struct stat *, struct linux_stat *);
   75 #endif
   76 
   77 conv_linux_flock(linux, flock)
   78 
   79 /*
   80  * Some file-related calls are handled here. The usual flag conversion
   81  * an structure conversion is done, and alternate emul path searching.
   82  */
   83 
   84 /*
   85  * The next two functions convert between the Linux and NetBSD values
   86  * of the flags used in open(2) and fcntl(2).
   87  */
   88 static int
   89 linux_to_bsd_ioflags(int lflags)
   90 {
   91         int res = 0;
   92 
   93         res |= cvtto_bsd_mask(lflags, LINUX_O_WRONLY, O_WRONLY);
   94         res |= cvtto_bsd_mask(lflags, LINUX_O_RDONLY, O_RDONLY);
   95         res |= cvtto_bsd_mask(lflags, LINUX_O_RDWR, O_RDWR);
   96         res |= cvtto_bsd_mask(lflags, LINUX_O_CREAT, O_CREAT);
   97         res |= cvtto_bsd_mask(lflags, LINUX_O_EXCL, O_EXCL);
   98         res |= cvtto_bsd_mask(lflags, LINUX_O_NOCTTY, O_NOCTTY);
   99         res |= cvtto_bsd_mask(lflags, LINUX_O_TRUNC, O_TRUNC);
  100         res |= cvtto_bsd_mask(lflags, LINUX_O_NDELAY, O_NDELAY);
  101         res |= cvtto_bsd_mask(lflags, LINUX_O_SYNC, O_FSYNC);
  102         res |= cvtto_bsd_mask(lflags, LINUX_FASYNC, O_ASYNC);
  103         res |= cvtto_bsd_mask(lflags, LINUX_O_APPEND, O_APPEND);
  104 
  105         return res;
  106 }
  107 
  108 static int
  109 bsd_to_linux_ioflags(int bflags)
  110 {
  111         int res = 0;
  112 
  113         res |= cvtto_linux_mask(bflags, O_WRONLY, LINUX_O_WRONLY);
  114         res |= cvtto_linux_mask(bflags, O_RDONLY, LINUX_O_RDONLY);
  115         res |= cvtto_linux_mask(bflags, O_RDWR, LINUX_O_RDWR);
  116         res |= cvtto_linux_mask(bflags, O_CREAT, LINUX_O_CREAT);
  117         res |= cvtto_linux_mask(bflags, O_EXCL, LINUX_O_EXCL);
  118         res |= cvtto_linux_mask(bflags, O_NOCTTY, LINUX_O_NOCTTY);
  119         res |= cvtto_linux_mask(bflags, O_TRUNC, LINUX_O_TRUNC);
  120         res |= cvtto_linux_mask(bflags, O_NDELAY, LINUX_O_NDELAY);
  121         res |= cvtto_linux_mask(bflags, O_FSYNC, LINUX_O_SYNC);
  122         res |= cvtto_linux_mask(bflags, O_ASYNC, LINUX_FASYNC);
  123         res |= cvtto_linux_mask(bflags, O_APPEND, LINUX_O_APPEND);
  124 
  125         return res;
  126 }
  127 
  128 /*
  129  * creat(2) is an obsolete function, but it's present as a Linux
  130  * system call, so let's deal with it.
  131  *
  132  * Note: On the Alpha this doesn't really exist in Linux, but it's defined
  133  * in syscalls.master anyway so this doesn't have to be special cased.
  134  *
  135  * Just call open(2) with the TRUNC, CREAT and WRONLY flags.
  136  */
  137 int
  138 linux_sys_creat(struct lwp *l, const struct linux_sys_creat_args *uap, register_t *retval)
  139 {
  140         /* {
  141                 syscallarg(const char *) path;
  142                 syscallarg(int) mode;
  143         } */
  144         struct sys_open_args oa;
  145 
  146         SCARG(&oa, path) = SCARG(uap, path);
  147         SCARG(&oa, flags) = O_CREAT | O_TRUNC | O_WRONLY;
  148         SCARG(&oa, mode) = SCARG(uap, mode);
  149 
  150         return sys_open(l, &oa, retval);
  151 }
  152 
  153 /*
  154  * open(2). Take care of the different flag values, and let the
  155  * NetBSD syscall do the real work. See if this operation
  156  * gives the current process a controlling terminal.
  157  * (XXX is this necessary?)
  158  */
  159 int
  160 linux_sys_open(struct lwp *l, const struct linux_sys_open_args *uap, register_t *retval)
  161 {
  162         /* {
  163                 syscallarg(const char *) path;
  164                 syscallarg(int) flags;
  165                 syscallarg(int) mode;
  166         } */
  167         struct proc *p = l->l_proc;
  168         int error, fl;
  169         struct sys_open_args boa;
  170 
  171         fl = linux_to_bsd_ioflags(SCARG(uap, flags));
  172 
  173         SCARG(&boa, path) = SCARG(uap, path);
  174         SCARG(&boa, flags) = fl;
  175         SCARG(&boa, mode) = SCARG(uap, mode);
  176 
  177         if ((error = sys_open(l, &boa, retval)))
  178                 return error;
  179 
  180         /*
  181          * this bit from sunos_misc.c (and svr4_fcntl.c).
  182          * If we are a session leader, and we don't have a controlling
  183          * terminal yet, and the O_NOCTTY flag is not set, try to make
  184          * this the controlling terminal.
  185          */
  186         if (!(fl & O_NOCTTY) && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
  187                 file_t *fp;
  188 
  189                 fp = fd_getfile(*retval);
  190 
  191                 /* ignore any error, just give it a try */
  192                 if (fp != NULL) {
  193                         if (fp->f_type == DTYPE_VNODE) {
  194                                 (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, NULL);
  195                         }
  196                         fd_putfile(*retval);
  197                 }
  198         }
  199         return 0;
  200 }
  201 
  202 /*
  203  * Most actions in the fcntl() call are straightforward; simply
  204  * pass control to the NetBSD system call. A few commands need
  205  * conversions after the actual system call has done its work,
  206  * because the flag values and lock structure are different.
  207  */
  208 int
  209 linux_sys_fcntl(struct lwp *l, const struct linux_sys_fcntl_args *uap, register_t *retval)
  210 {
  211         /* {
  212                 syscallarg(int) fd;
  213                 syscallarg(int) cmd;
  214                 syscallarg(void *) arg;
  215         } */
  216         struct proc *p = l->l_proc;
  217         int fd, cmd, error;
  218         u_long val;
  219         void *arg;
  220         struct sys_fcntl_args fca;
  221         file_t *fp;
  222         struct vnode *vp;
  223         struct vattr va;
  224         long pgid;
  225         struct pgrp *pgrp;
  226         struct tty *tp;
  227 
  228         fd = SCARG(uap, fd);
  229         cmd = SCARG(uap, cmd);
  230         arg = SCARG(uap, arg);
  231 
  232         switch (cmd) {
  233 
  234         case LINUX_F_DUPFD:
  235                 cmd = F_DUPFD;
  236                 break;
  237 
  238         case LINUX_F_GETFD:
  239                 cmd = F_GETFD;
  240                 break;
  241 
  242         case LINUX_F_SETFD:
  243                 cmd = F_SETFD;
  244                 break;
  245 
  246         case LINUX_F_GETFL:
  247                 SCARG(&fca, fd) = fd;
  248                 SCARG(&fca, cmd) = F_GETFL;
  249                 SCARG(&fca, arg) = arg;
  250                 if ((error = sys_fcntl(l, &fca, retval)))
  251                         return error;
  252                 retval[0] = bsd_to_linux_ioflags(retval[0]);
  253                 return 0;
  254 
  255         case LINUX_F_SETFL: {
  256                 file_t  *fp1 = NULL;
  257 
  258                 val = linux_to_bsd_ioflags((unsigned long)SCARG(uap, arg));
  259                 /*
  260                  * Linux seems to have same semantics for sending SIGIO to the
  261                  * read side of socket, but slightly different semantics
  262                  * for SIGIO to the write side.  Rather than sending the SIGIO
  263                  * every time it's possible to write (directly) more data, it
  264                  * only sends SIGIO if last write(2) failed due to insufficient
  265                  * memory to hold the data. This is compatible enough
  266                  * with NetBSD semantics to not do anything about the
  267                  * difference.
  268                  *
  269                  * Linux does NOT send SIGIO for pipes. Deal with socketpair
  270                  * ones and DTYPE_PIPE ones. For these, we don't set
  271                  * the underlying flags (we don't pass O_ASYNC flag down
  272                  * to sys_fcntl()), but set the FASYNC flag for file descriptor,
  273                  * so that F_GETFL would report the ASYNC i/o is on.
  274                  */
  275                 if (val & O_ASYNC) {
  276                         if (((fp1 = fd_getfile(fd)) == NULL))
  277                             return (EBADF);
  278                         if (((fp1->f_type == DTYPE_SOCKET) && fp1->f_data
  279                               && ((struct socket *)fp1->f_data)->so_state & SS_ISAPIPE)
  280                             || (fp1->f_type == DTYPE_PIPE))
  281                                 val &= ~O_ASYNC;
  282                         else {
  283                                 /* not a pipe, do not modify anything */
  284                                 fd_putfile(fd);
  285                                 fp1 = NULL;
  286                         }
  287                 }
  288 
  289                 SCARG(&fca, fd) = fd;
  290                 SCARG(&fca, cmd) = F_SETFL;
  291                 SCARG(&fca, arg) = (void *) val;
  292 
  293                 error = sys_fcntl(l, &fca, retval);
  294 
  295                 /* Now set the FASYNC flag for pipes */
  296                 if (fp1) {
  297                         if (!error) {
  298                                 mutex_enter(&fp1->f_lock);
  299                                 fp1->f_flag |= FASYNC;
  300                                 mutex_exit(&fp1->f_lock);
  301                         }
  302                         fd_putfile(fd);
  303                 }
  304 
  305                 return (error);
  306             }
  307 
  308         case LINUX_F_GETLK:
  309                 do_linux_getlk(fd, cmd, arg, linux, flock);
  310 
  311         case LINUX_F_SETLK:
  312         case LINUX_F_SETLKW:
  313                 do_linux_setlk(fd, cmd, arg, linux, flock, LINUX_F_SETLK);
  314 
  315         case LINUX_F_SETOWN:
  316         case LINUX_F_GETOWN:
  317                 /*
  318                  * We need to route fcntl() for tty descriptors around normal
  319                  * fcntl(), since NetBSD tty TIOC{G,S}PGRP semantics is too
  320                  * restrictive for Linux F_{G,S}ETOWN. For non-tty descriptors,
  321                  * this is not a problem.
  322                  */
  323                 if ((fp = fd_getfile(fd)) == NULL)
  324                         return EBADF;
  325 
  326                 /* Check it's a character device vnode */
  327                 if (fp->f_type != DTYPE_VNODE
  328                     || (vp = (struct vnode *)fp->f_data) == NULL
  329                     || vp->v_type != VCHR) {
  330                         fd_putfile(fd);
  331 
  332             not_tty:
  333                         /* Not a tty, proceed with common fcntl() */
  334                         cmd = cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
  335                         break;
  336                 }
  337 
  338                 error = VOP_GETATTR(vp, &va, l->l_cred);
  339 
  340                 fd_putfile(fd);
  341 
  342                 if (error)
  343                         return error;
  344 
  345                 if ((tp = cdev_tty(va.va_rdev)) == NULL)
  346                         goto not_tty;
  347 
  348                 /* set tty pg_id appropriately */
  349                 mutex_enter(proc_lock);
  350                 if (cmd == LINUX_F_GETOWN) {
  351                         retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
  352                         mutex_exit(proc_lock);
  353                         return 0;
  354                 }
  355                 if ((long)arg <= 0) {
  356                         pgid = -(long)arg;
  357                 } else {
  358                         struct proc *p1 = p_find((long)arg, PFIND_LOCKED | PFIND_UNLOCK_FAIL);
  359                         if (p1 == NULL)
  360                                 return (ESRCH);
  361                         pgid = (long)p1->p_pgrp->pg_id;
  362                 }
  363                 pgrp = pg_find(pgid, PFIND_LOCKED);
  364                 if (pgrp == NULL || pgrp->pg_session != p->p_session) {
  365                         mutex_exit(proc_lock);
  366                         return EPERM;
  367                 }
  368                 tp->t_pgrp = pgrp;
  369                 mutex_exit(proc_lock);
  370                 return 0;
  371 
  372         default:
  373                 return EOPNOTSUPP;
  374         }
  375 
  376         SCARG(&fca, fd) = fd;
  377         SCARG(&fca, cmd) = cmd;
  378         SCARG(&fca, arg) = arg;
  379 
  380         return sys_fcntl(l, &fca, retval);
  381 }
  382 
  383 #if !defined(__amd64__)
  384 /*
  385  * Convert a NetBSD stat structure to a Linux stat structure.
  386  * Only the order of the fields and the padding in the structure
  387  * is different. linux_fakedev is a machine-dependent function
  388  * which optionally converts device driver major/minor numbers
  389  * (XXX horrible, but what can you do against code that compares
  390  * things against constant major device numbers? sigh)
  391  */
  392 static void
  393 bsd_to_linux_stat(struct stat *bsp, struct linux_stat *lsp)
  394 {
  395 
  396         lsp->lst_dev     = linux_fakedev(bsp->st_dev, 0);
  397         lsp->lst_ino     = bsp->st_ino;
  398         lsp->lst_mode    = (linux_mode_t)bsp->st_mode;
  399         if (bsp->st_nlink >= (1 << 15))
  400                 lsp->lst_nlink = (1 << 15) - 1;
  401         else
  402                 lsp->lst_nlink = (linux_nlink_t)bsp->st_nlink;
  403         lsp->lst_uid     = bsp->st_uid;
  404         lsp->lst_gid     = bsp->st_gid;
  405         lsp->lst_rdev    = linux_fakedev(bsp->st_rdev, 1);
  406         lsp->lst_size    = bsp->st_size;
  407         lsp->lst_blksize = bsp->st_blksize;
  408         lsp->lst_blocks  = bsp->st_blocks;
  409         lsp->lst_atime   = bsp->st_atime;
  410         lsp->lst_mtime   = bsp->st_mtime;
  411         lsp->lst_ctime   = bsp->st_ctime;
  412 #ifdef LINUX_STAT_HAS_NSEC
  413         lsp->lst_atime_nsec   = bsp->st_atimensec;
  414         lsp->lst_mtime_nsec   = bsp->st_mtimensec;
  415         lsp->lst_ctime_nsec   = bsp->st_ctimensec;
  416 #endif
  417 }
  418 
  419 /*
  420  * The stat functions below are plain sailing. stat and lstat are handled
  421  * by one function to avoid code duplication.
  422  */
  423 int
  424 linux_sys_fstat(struct lwp *l, const struct linux_sys_fstat_args *uap, register_t *retval)
  425 {
  426         /* {
  427                 syscallarg(int) fd;
  428                 syscallarg(linux_stat *) sp;
  429         } */
  430         struct linux_stat tmplst;
  431         struct stat tmpst;
  432         int error;
  433 
  434         error = do_sys_fstat(SCARG(uap, fd), &tmpst);
  435         if (error != 0)
  436                 return error;
  437         bsd_to_linux_stat(&tmpst, &tmplst);
  438 
  439         return copyout(&tmplst, SCARG(uap, sp), sizeof tmplst);
  440 }
  441 
  442 static int
  443 linux_stat1(const struct linux_sys_stat_args *uap, register_t *retval, int flags)
  444 {
  445         struct linux_stat tmplst;
  446         struct stat tmpst;
  447         int error;
  448 
  449         error = do_sys_stat(SCARG(uap, path), flags, &tmpst);
  450         if (error != 0)
  451                 return error;
  452 
  453         bsd_to_linux_stat(&tmpst, &tmplst);
  454 
  455         return copyout(&tmplst, SCARG(uap, sp), sizeof tmplst);
  456 }
  457 
  458 int
  459 linux_sys_stat(struct lwp *l, const struct linux_sys_stat_args *uap, register_t *retval)
  460 {
  461         /* {
  462                 syscallarg(const char *) path;
  463                 syscallarg(struct linux_stat *) sp;
  464         } */
  465 
  466         return linux_stat1(uap, retval, FOLLOW);
  467 }
  468 
  469 /* Note: this is "newlstat" in the Linux sources */
  470 /*      (we don't bother with the old lstat currently) */
  471 int
  472 linux_sys_lstat(struct lwp *l, const struct linux_sys_lstat_args *uap, register_t *retval)
  473 {
  474         /* {
  475                 syscallarg(const char *) path;
  476                 syscallarg(struct linux_stat *) sp;
  477         } */
  478 
  479         return linux_stat1((const void *)uap, retval, NOFOLLOW);
  480 }
  481 #endif /* !__amd64__ */
  482 
  483 /*
  484  * The following syscalls are mostly here because of the alternate path check.
  485  */
  486 int
  487 linux_sys_unlink(struct lwp *l, const struct linux_sys_unlink_args *uap, register_t *retval)
  488 {
  489         /* {
  490                 syscallarg(const char *) path;
  491         } */
  492         int error;
  493         struct nameidata nd;
  494 
  495         error = sys_unlink(l, (const void *)uap, retval);
  496         if (error != EPERM)
  497                 return (error);
  498 
  499         /*
  500          * Linux returns EISDIR if unlink(2) is called on a directory.
  501          * We return EPERM in such cases. To emulate correct behaviour,
  502          * check if the path points to directory and return EISDIR if this
  503          * is the case.
  504          */
  505         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, UIO_USERSPACE,
  506             SCARG(uap, path));
  507         if (namei(&nd) == 0) {
  508                 struct stat sb;
  509 
  510                 if (vn_stat(nd.ni_vp, &sb) == 0
  511                     && S_ISDIR(sb.st_mode))
  512                         error = EISDIR;
  513 
  514                 vput(nd.ni_vp);
  515         }
  516 
  517         return (error);
  518 }
  519 
  520 int
  521 linux_sys_mknod(struct lwp *l, const struct linux_sys_mknod_args *uap, register_t *retval)
  522 {
  523         /* {
  524                 syscallarg(const char *) path;
  525                 syscallarg(int) mode;
  526                 syscallarg(int) dev;
  527         } */
  528 
  529         /*
  530          * BSD handles FIFOs separately
  531          */
  532         if (S_ISFIFO(SCARG(uap, mode))) {
  533                 struct sys_mkfifo_args bma;
  534 
  535                 SCARG(&bma, path) = SCARG(uap, path);
  536                 SCARG(&bma, mode) = SCARG(uap, mode);
  537                 return sys_mkfifo(l, &bma, retval);
  538         } else {
  539                 struct sys_mknod_args bma;
  540 
  541                 SCARG(&bma, path) = SCARG(uap, path);
  542                 SCARG(&bma, mode) = SCARG(uap, mode);
  543                 /*
  544                  * Linux device numbers uses 8 bits for minor and 8 bits
  545                  * for major. Due to how we map our major and minor,
  546                  * this just fits into our dev_t. Just mask off the
  547                  * upper 16bit to remove any random junk.
  548                  */
  549                 SCARG(&bma, dev) = SCARG(uap, dev) & 0xffff;
  550                 return sys_mknod(l, &bma, retval);
  551         }
  552 }
  553 
  554 /*
  555  * This is just fsync() for now (just as it is in the Linux kernel)
  556  * Note: this is not implemented under Linux on Alpha and Arm
  557  *      but should still be defined in our syscalls.master.
  558  *      (syscall #148 on the arm)
  559  */
  560 int
  561 linux_sys_fdatasync(struct lwp *l, const struct linux_sys_fdatasync_args *uap, register_t *retval)
  562 {
  563         /* {
  564                 syscallarg(int) fd;
  565         } */
  566 
  567         return sys_fsync(l, (const void *)uap, retval);
  568 }
  569 
  570 /*
  571  * pread(2).
  572  */
  573 int
  574 linux_sys_pread(struct lwp *l, const struct linux_sys_pread_args *uap, register_t *retval)
  575 {
  576         /* {
  577                 syscallarg(int) fd;
  578                 syscallarg(void *) buf;
  579                 syscallarg(size_t) nbyte;
  580                 syscallarg(linux_off_t) offset;
  581         } */
  582         struct sys_pread_args pra;
  583 
  584         SCARG(&pra, fd) = SCARG(uap, fd);
  585         SCARG(&pra, buf) = SCARG(uap, buf);
  586         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  587         SCARG(&pra, offset) = SCARG(uap, offset);
  588 
  589         return sys_pread(l, &pra, retval);
  590 }
  591 
  592 /*
  593  * pwrite(2).
  594  */
  595 int
  596 linux_sys_pwrite(struct lwp *l, const struct linux_sys_pwrite_args *uap, register_t *retval)
  597 {
  598         /* {
  599                 syscallarg(int) fd;
  600                 syscallarg(void *) buf;
  601                 syscallarg(size_t) nbyte;
  602                 syscallarg(linux_off_t) offset;
  603         } */
  604         struct sys_pwrite_args pra;
  605 
  606         SCARG(&pra, fd) = SCARG(uap, fd);
  607         SCARG(&pra, buf) = SCARG(uap, buf);
  608         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  609         SCARG(&pra, offset) = SCARG(uap, offset);
  610 
  611         return sys_pwrite(l, &pra, retval);
  612 }
  613 
  614 #define LINUX_NOT_SUPPORTED(fun) \
  615 int \
  616 fun(struct lwp *l, const struct fun##_args *uap, register_t *retval) \
  617 { \
  618         return EOPNOTSUPP; \
  619 }
  620 
  621 LINUX_NOT_SUPPORTED(linux_sys_setxattr)
  622 LINUX_NOT_SUPPORTED(linux_sys_lsetxattr)
  623 LINUX_NOT_SUPPORTED(linux_sys_fsetxattr)
  624 
  625 LINUX_NOT_SUPPORTED(linux_sys_getxattr)
  626 LINUX_NOT_SUPPORTED(linux_sys_lgetxattr)
  627 LINUX_NOT_SUPPORTED(linux_sys_fgetxattr)
  628 
  629 LINUX_NOT_SUPPORTED(linux_sys_listxattr)
  630 LINUX_NOT_SUPPORTED(linux_sys_llistxattr)
  631 LINUX_NOT_SUPPORTED(linux_sys_flistxattr)
  632 
  633 LINUX_NOT_SUPPORTED(linux_sys_removexattr)
  634 LINUX_NOT_SUPPORTED(linux_sys_lremovexattr)
  635 LINUX_NOT_SUPPORTED(linux_sys_fremovexattr)
  636 

Cache object: 8d81bb154bfee9215bfee7e7918b3c0d


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