root/compat/linux/linux_file.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. linux_to_bsd_ioflags
  2. bsd_to_linux_ioflags
  3. linux_sys_creat
  4. linux_sys_open
  5. linux_sys_llseek
  6. bsd_to_linux_flock
  7. linux_to_bsd_flock
  8. linux_sys_fcntl
  9. bsd_to_linux_stat
  10. linux_sys_fstat
  11. linux_stat1
  12. linux_sys_stat
  13. linux_sys_lstat
  14. linux_sys_access
  15. linux_sys_unlink
  16. linux_sys_chdir
  17. linux_sys_mknod
  18. linux_sys_chmod
  19. linux_sys_chown16
  20. linux_sys_fchown16
  21. linux_sys_lchown16
  22. linux_sys_rename
  23. linux_sys_mkdir
  24. linux_sys_rmdir
  25. linux_sys_symlink
  26. linux_sys_readlink
  27. linux_sys_truncate
  28. linux_sys_fdatasync
  29. linux_sys_pread
  30. linux_sys_pwrite

    1 /*      $OpenBSD: linux_file.c,v 1.23 2006/09/25 07:12:57 otto Exp $    */
    2 /*      $NetBSD: linux_file.c,v 1.15 1996/05/20 01:59:09 fvdl Exp $     */
    3 
    4 /*
    5  * Copyright (c) 1995 Frank van der Linden
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed for the NetBSD Project
   19  *      by Frank van der Linden
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/namei.h>
   38 #include <sys/proc.h>
   39 #include <sys/file.h>
   40 #include <sys/stat.h>
   41 #include <sys/filedesc.h>
   42 #include <sys/ioctl.h>
   43 #include <sys/kernel.h>
   44 #include <sys/mount.h>
   45 #include <sys/signalvar.h>
   46 #include <sys/uio.h>
   47 #include <sys/malloc.h>
   48 #include <sys/vnode.h>
   49 #include <sys/tty.h>
   50 #include <sys/conf.h>
   51 
   52 #include <sys/syscallargs.h>
   53 
   54 #include <compat/linux/linux_types.h>
   55 #include <compat/linux/linux_signal.h>
   56 #include <compat/linux/linux_syscallargs.h>
   57 #include <compat/linux/linux_fcntl.h>
   58 #include <compat/linux/linux_util.h>
   59 
   60 #include <machine/linux_machdep.h>
   61 
   62 static int linux_to_bsd_ioflags(int);
   63 static int bsd_to_linux_ioflags(int);
   64 static void bsd_to_linux_flock(struct flock *, struct linux_flock *);
   65 static void linux_to_bsd_flock(struct linux_flock *, struct flock *);
   66 static void bsd_to_linux_stat(struct stat *, struct linux_stat *);
   67 static int linux_stat1(struct proc *, void *, register_t *, int);
   68 
   69 
   70 /*
   71  * Some file-related calls are handled here. The usual flag conversion
   72  * an structure conversion is done, and alternate emul path searching.
   73  */
   74 
   75 /*
   76  * The next two functions convert between the Linux and OpenBSD values
   77  * of the flags used in open(2) and fcntl(2).
   78  */
   79 static int
   80 linux_to_bsd_ioflags(lflags)
   81         int lflags;
   82 {
   83         int res = 0;
   84 
   85         res |= cvtto_bsd_mask(lflags, LINUX_O_WRONLY, O_WRONLY);
   86         res |= cvtto_bsd_mask(lflags, LINUX_O_RDONLY, O_RDONLY);
   87         res |= cvtto_bsd_mask(lflags, LINUX_O_RDWR, O_RDWR);
   88         res |= cvtto_bsd_mask(lflags, LINUX_O_CREAT, O_CREAT);
   89         res |= cvtto_bsd_mask(lflags, LINUX_O_EXCL, O_EXCL);
   90         res |= cvtto_bsd_mask(lflags, LINUX_O_NOCTTY, O_NOCTTY);
   91         res |= cvtto_bsd_mask(lflags, LINUX_O_TRUNC, O_TRUNC);
   92         res |= cvtto_bsd_mask(lflags, LINUX_O_NDELAY, O_NDELAY);
   93         res |= cvtto_bsd_mask(lflags, LINUX_O_SYNC, O_SYNC);
   94         res |= cvtto_bsd_mask(lflags, LINUX_FASYNC, O_ASYNC);
   95         res |= cvtto_bsd_mask(lflags, LINUX_O_APPEND, O_APPEND);
   96 
   97         return res;
   98 }
   99 
  100 static int
  101 bsd_to_linux_ioflags(bflags)
  102         int bflags;
  103 {
  104         int res = 0;
  105 
  106         res |= cvtto_linux_mask(bflags, O_WRONLY, LINUX_O_WRONLY);
  107         res |= cvtto_linux_mask(bflags, O_RDONLY, LINUX_O_RDONLY);
  108         res |= cvtto_linux_mask(bflags, O_RDWR, LINUX_O_RDWR);
  109         res |= cvtto_linux_mask(bflags, O_CREAT, LINUX_O_CREAT);
  110         res |= cvtto_linux_mask(bflags, O_EXCL, LINUX_O_EXCL);
  111         res |= cvtto_linux_mask(bflags, O_NOCTTY, LINUX_O_NOCTTY);
  112         res |= cvtto_linux_mask(bflags, O_TRUNC, LINUX_O_TRUNC);
  113         res |= cvtto_linux_mask(bflags, O_NDELAY, LINUX_O_NDELAY);
  114         res |= cvtto_linux_mask(bflags, O_SYNC, LINUX_O_SYNC);
  115         res |= cvtto_linux_mask(bflags, O_ASYNC, LINUX_FASYNC);
  116         res |= cvtto_linux_mask(bflags, O_APPEND, LINUX_O_APPEND);
  117 
  118         return res;
  119 }
  120 
  121 /*
  122  * creat(2) is an obsolete function, but it's present as a Linux
  123  * system call, so let's deal with it.
  124  *
  125  * Just call open(2) with the TRUNC, CREAT and WRONLY flags.
  126  */
  127 int
  128 linux_sys_creat(p, v, retval)
  129         struct proc *p;
  130         void *v;
  131         register_t *retval;
  132 {
  133         struct linux_sys_creat_args /* {
  134                 syscallarg(char *) path;
  135                 syscallarg(int) mode;
  136         } */ *uap = v;
  137         struct sys_open_args oa;
  138         caddr_t sg;
  139 
  140         sg = stackgap_init(p->p_emul);
  141         LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  142 
  143         SCARG(&oa, path) = SCARG(uap, path);
  144         SCARG(&oa, flags) = O_CREAT | O_TRUNC | O_WRONLY;
  145         SCARG(&oa, mode) = SCARG(uap, mode);
  146 
  147         return sys_open(p, &oa, retval);
  148 }
  149 
  150 /*
  151  * open(2). Take care of the different flag values, and let the
  152  * OpenBSD syscall do the real work. See if this operation
  153  * gives the current process a controlling terminal.
  154  * (XXX is this necessary?)
  155  */
  156 int
  157 linux_sys_open(p, v, retval)
  158         struct proc *p;
  159         void *v;
  160         register_t *retval;
  161 {
  162         struct linux_sys_open_args /* {
  163                 syscallarg(char *) path;
  164                 syscallarg(int) flags;
  165                 syscallarg(int) mode;
  166         } */ *uap = v;
  167         int error, fl;
  168         struct sys_open_args boa;
  169         caddr_t sg;
  170 
  171         sg = stackgap_init(p->p_emul);
  172 
  173         fl = linux_to_bsd_ioflags(SCARG(uap, flags));
  174 
  175         if (fl & O_CREAT)
  176                 LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  177         else
  178                 LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  179 
  180         SCARG(&boa, path) = SCARG(uap, path);
  181         SCARG(&boa, flags) = fl;
  182         SCARG(&boa, mode) = SCARG(uap, mode);
  183 
  184         if ((error = sys_open(p, &boa, retval)))
  185                 return error;
  186 
  187         /*
  188          * this bit from sunos_misc.c (and svr4_fcntl.c).
  189          * If we are a session leader, and we don't have a controlling
  190          * terminal yet, and the O_NOCTTY flag is not set, try to make
  191          * this the controlling terminal.
  192          */ 
  193         if (!(fl & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
  194                 struct filedesc *fdp = p->p_fd;
  195                 struct file     *fp;
  196 
  197                 if ((fp = fd_getfile(fdp, *retval)) == NULL)
  198                         return (EBADF);
  199                 FREF(fp);
  200                 if (fp->f_type == DTYPE_VNODE)
  201                         (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, p);
  202                 FRELE(fp);
  203         }
  204         return 0;
  205 }
  206 
  207 /*
  208  * This appears to be part of a Linux attempt to switch to 64 bits file sizes.
  209  */
  210 int
  211 linux_sys_llseek(p, v, retval)
  212         struct proc *p;
  213         void *v;
  214         register_t *retval;
  215 {
  216         struct linux_sys_llseek_args /* {
  217                 syscallarg(int) fd;
  218                 syscallarg(uint32_t) ohigh;
  219                 syscallarg(uint32_t) olow;
  220                 syscallarg(caddr_t) res;
  221                 syscallarg(int) whence;
  222         } */ *uap = v;
  223         struct sys_lseek_args bla;
  224         int error;
  225         off_t off;
  226 
  227         off = SCARG(uap, olow) | (((off_t) SCARG(uap, ohigh)) << 32);
  228 
  229         SCARG(&bla, fd) = SCARG(uap, fd);
  230         SCARG(&bla, offset) = off;
  231         SCARG(&bla, whence) = SCARG(uap, whence);
  232 
  233         if ((error = sys_lseek(p, &bla, retval)))
  234                 return error;
  235 
  236         if ((error = copyout(retval, SCARG(uap, res), sizeof (off_t))))
  237                 return error;
  238 
  239         retval[0] = 0;
  240         return 0;
  241 }
  242 
  243 /*
  244  * The next two functions take care of converting the flock
  245  * structure back and forth between Linux and OpenBSD format.
  246  * The only difference in the structures is the order of
  247  * the fields, and the 'whence' value.
  248  */
  249 static void
  250 bsd_to_linux_flock(bfp, lfp)
  251         struct flock *bfp;
  252         struct linux_flock *lfp;
  253 {
  254 
  255         lfp->l_start = bfp->l_start;
  256         lfp->l_len = bfp->l_len;
  257         lfp->l_pid = bfp->l_pid;
  258         lfp->l_whence = bfp->l_whence;
  259         switch (bfp->l_type) {
  260         case F_RDLCK:
  261                 lfp->l_type = LINUX_F_RDLCK;
  262                 break;
  263         case F_UNLCK:
  264                 lfp->l_type = LINUX_F_UNLCK;
  265                 break;
  266         case F_WRLCK:
  267                 lfp->l_type = LINUX_F_WRLCK;
  268                 break;
  269         }
  270 }
  271 
  272 static void
  273 linux_to_bsd_flock(lfp, bfp)
  274         struct linux_flock *lfp;
  275         struct flock *bfp;
  276 {
  277 
  278         bfp->l_start = lfp->l_start;
  279         bfp->l_len = lfp->l_len;
  280         bfp->l_pid = lfp->l_pid;
  281         bfp->l_whence = lfp->l_whence;
  282         switch (lfp->l_type) {
  283         case LINUX_F_RDLCK:
  284                 bfp->l_type = F_RDLCK;
  285                 break;
  286         case LINUX_F_UNLCK:
  287                 bfp->l_type = F_UNLCK;
  288                 break;
  289         case LINUX_F_WRLCK:
  290                 bfp->l_type = F_WRLCK;
  291                 break;
  292         }
  293 }
  294 
  295 /*
  296  * Most actions in the fcntl() call are straightforward; simply
  297  * pass control to the OpenBSD system call. A few commands need
  298  * conversions after the actual system call has done its work,
  299  * because the flag values and lock structure are different.
  300  */
  301 int
  302 linux_sys_fcntl(p, v, retval)
  303         struct proc *p;
  304         void *v;
  305         register_t *retval;
  306 {
  307         struct linux_sys_fcntl_args /* {
  308                 syscallarg(int) fd;
  309                 syscallarg(int) cmd;
  310                 syscallarg(void *) arg;
  311         } */ *uap = v;
  312         int fd, cmd, error, val;
  313         caddr_t arg, sg;
  314         struct linux_flock lfl;
  315         struct flock *bfp, bfl;
  316         struct sys_fcntl_args fca;
  317         struct filedesc *fdp;
  318         struct file *fp;
  319         struct vnode *vp;
  320         struct vattr va;
  321         long pgid;
  322         struct pgrp *pgrp;
  323         struct tty *tp, *(*d_tty)(dev_t);
  324 
  325         fd = SCARG(uap, fd);
  326         cmd = SCARG(uap, cmd);
  327         arg = (caddr_t) SCARG(uap, arg);
  328 
  329         switch (cmd) {
  330         case LINUX_F_DUPFD:
  331                 cmd = F_DUPFD;
  332                 break;
  333         case LINUX_F_GETFD:
  334                 cmd = F_GETFD;
  335                 break;
  336         case LINUX_F_SETFD:
  337                 cmd = F_SETFD;
  338                 break;
  339         case LINUX_F_GETFL:
  340                 SCARG(&fca, fd) = fd;
  341                 SCARG(&fca, cmd) = F_GETFL;
  342                 SCARG(&fca, arg) = arg;
  343                 if ((error = sys_fcntl(p, &fca, retval)))
  344                         return error;
  345                 retval[0] = bsd_to_linux_ioflags(retval[0]);
  346                 return 0;
  347         case LINUX_F_SETFL:
  348                 val = linux_to_bsd_ioflags((int)SCARG(uap, arg));
  349                 SCARG(&fca, fd) = fd;
  350                 SCARG(&fca, cmd) = F_SETFL;
  351                 SCARG(&fca, arg) = (caddr_t) val;
  352                 return sys_fcntl(p, &fca, retval);
  353         case LINUX_F_GETLK:
  354                 sg = stackgap_init(p->p_emul);
  355                 if ((error = copyin(arg, &lfl, sizeof lfl)))
  356                         return error;
  357                 linux_to_bsd_flock(&lfl, &bfl);
  358                 bfp = (struct flock *) stackgap_alloc(&sg, sizeof *bfp);
  359                 SCARG(&fca, fd) = fd;
  360                 SCARG(&fca, cmd) = F_GETLK;
  361                 SCARG(&fca, arg) = bfp;
  362                 if ((error = copyout(&bfl, bfp, sizeof bfl)))
  363                         return error;
  364                 if ((error = sys_fcntl(p, &fca, retval)))
  365                         return error;
  366                 if ((error = copyin(bfp, &bfl, sizeof bfl)))
  367                         return error;
  368                 bsd_to_linux_flock(&bfl, &lfl);
  369                 error = copyout(&lfl, arg, sizeof lfl);
  370                 return error;
  371                 break;
  372         case LINUX_F_SETLK:
  373         case LINUX_F_SETLKW:
  374                 cmd = (cmd == LINUX_F_SETLK ? F_SETLK : F_SETLKW);
  375                 if ((error = copyin(arg, &lfl, sizeof lfl)))
  376                         return error;
  377                 linux_to_bsd_flock(&lfl, &bfl);
  378                 sg = stackgap_init(p->p_emul);
  379                 bfp = (struct flock *) stackgap_alloc(&sg, sizeof *bfp);
  380                 if ((error = copyout(&bfl, bfp, sizeof bfl)))
  381                         return error;
  382                 SCARG(&fca, fd) = fd;
  383                 SCARG(&fca, cmd) = cmd;
  384                 SCARG(&fca, arg) = bfp;
  385                 return sys_fcntl(p, &fca, retval);
  386                 break;
  387         case LINUX_F_SETOWN:
  388         case LINUX_F_GETOWN:    
  389                 /*
  390                  * We need to route around the normal fcntl() for these calls,
  391                  * since it uses TIOC{G,S}PGRP, which is too restrictive for
  392                  * Linux F_{G,S}ETOWN semantics. For sockets, this problem
  393                  * does not exist.
  394                  */
  395                 fdp = p->p_fd;
  396                 if ((fp = fd_getfile(fdp, fd)) == NULL)
  397                         return (EBADF);
  398                 if (fp->f_type == DTYPE_SOCKET) {
  399                         cmd = cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
  400                         break;
  401                 }
  402                 vp = (struct vnode *)fp->f_data;
  403                 if (vp->v_type != VCHR)
  404                         return EINVAL;
  405                 FREF(fp);
  406                 error = VOP_GETATTR(vp, &va, p->p_ucred, p);
  407                 FRELE(fp);
  408                 if (error)
  409                         return error;
  410                 d_tty = cdevsw[major(va.va_rdev)].d_tty;
  411                 if (!d_tty || (!(tp = (*d_tty)(va.va_rdev))))
  412                         return EINVAL;
  413                 if (cmd == LINUX_F_GETOWN) {
  414                         retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
  415                         return 0;
  416                 }
  417                 if ((long)arg <= 0) {
  418                         pgid = -(long)arg;
  419                 } else {
  420                         struct proc *p1 = pfind((long)arg);
  421                         if (p1 == 0)
  422                                 return (ESRCH);
  423                         pgid = (long)p1->p_pgrp->pg_id;
  424                 }
  425                 pgrp = pgfind(pgid);
  426                 if (pgrp == NULL || pgrp->pg_session != p->p_session)
  427                         return EPERM;
  428                 tp->t_pgrp = pgrp;
  429                 return 0;
  430         default:
  431                 return EOPNOTSUPP;
  432         }
  433 
  434         SCARG(&fca, fd) = fd;
  435         SCARG(&fca, cmd) = cmd;
  436         SCARG(&fca, arg) = arg;
  437 
  438         return sys_fcntl(p, &fca, retval);
  439 }
  440 
  441 /*
  442  * Convert a OpenBSD stat structure to a Linux stat structure.
  443  * Only the order of the fields and the padding in the structure
  444  * is different. linux_fakedev is a machine-dependent function
  445  * which optionally converts device driver major/minor numbers
  446  * (XXX horrible, but what can you do against code that compares
  447  * things against constant major device numbers? sigh)
  448  */
  449 static void
  450 bsd_to_linux_stat(bsp, lsp)
  451         struct stat *bsp;
  452         struct linux_stat *lsp;
  453 {
  454 
  455         lsp->lst_dev     = bsp->st_dev;
  456         lsp->lst_ino     = bsp->st_ino;
  457         lsp->lst_mode    = bsp->st_mode;
  458         lsp->lst_nlink   = bsp->st_nlink;
  459         lsp->lst_uid     = bsp->st_uid;
  460         lsp->lst_gid     = bsp->st_gid;
  461         lsp->lst_rdev    = linux_fakedev(bsp->st_rdev);
  462         lsp->lst_size    = bsp->st_size;
  463         lsp->lst_blksize = bsp->st_blksize;
  464         lsp->lst_blocks  = bsp->st_blocks;
  465         lsp->lst_atime   = bsp->st_atime;
  466         lsp->lst_mtime   = bsp->st_mtime;
  467         lsp->lst_ctime   = bsp->st_ctime;
  468 }
  469 
  470 /*
  471  * The stat functions below are plain sailing. stat and lstat are handled
  472  * by one function to avoid code duplication.
  473  */
  474 int
  475 linux_sys_fstat(p, v, retval)
  476         struct proc *p;
  477         void *v;
  478         register_t *retval;
  479 {
  480         struct linux_sys_fstat_args /* {
  481                 syscallarg(int) fd;
  482                 syscallarg(linux_stat *) sp;
  483         } */ *uap = v;
  484         struct sys_fstat_args fsa;
  485         struct linux_stat tmplst;
  486         struct stat *st,tmpst;
  487         caddr_t sg;
  488         int error;
  489 
  490         sg = stackgap_init(p->p_emul);
  491 
  492         st = stackgap_alloc(&sg, sizeof (struct stat));
  493 
  494         SCARG(&fsa, fd) = SCARG(uap, fd);
  495         SCARG(&fsa, sb) = st;
  496 
  497         if ((error = sys_fstat(p, &fsa, retval)))
  498                 return error;
  499 
  500         if ((error = copyin(st, &tmpst, sizeof tmpst)))
  501                 return error;
  502 
  503         bsd_to_linux_stat(&tmpst, &tmplst);
  504 
  505         if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst)))
  506                 return error;
  507 
  508         return 0;
  509 }
  510 
  511 static int
  512 linux_stat1(p, v, retval, dolstat)
  513         struct proc *p;
  514         void *v;
  515         register_t *retval;
  516         int dolstat;
  517 {
  518         struct sys_stat_args sa;
  519         struct linux_stat tmplst;
  520         struct stat *st, tmpst;
  521         caddr_t sg;
  522         int error;
  523         struct linux_sys_stat_args *uap = v;
  524 
  525         sg = stackgap_init(p->p_emul);
  526 
  527         st = stackgap_alloc(&sg, sizeof (struct stat));
  528         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  529 
  530         SCARG(&sa, ub) = st;
  531         SCARG(&sa, path) = SCARG(uap, path);
  532 
  533         if ((error = (dolstat ? sys_lstat(p, &sa, retval) :
  534                                 sys_stat(p, &sa, retval))))
  535                 return error;
  536 
  537         if ((error = copyin(st, &tmpst, sizeof tmpst)))
  538                 return error;
  539 
  540         bsd_to_linux_stat(&tmpst, &tmplst);
  541 
  542         if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst)))
  543                 return error;
  544 
  545         return 0;
  546 }
  547 
  548 int
  549 linux_sys_stat(p, v, retval)
  550         struct proc *p;
  551         void *v;
  552         register_t *retval;
  553 {
  554         struct linux_sys_stat_args /* {
  555                 syscallarg(char *) path;
  556                 syscallarg(struct linux_stat *) sp;
  557         } */ *uap = v;
  558 
  559         return linux_stat1(p, uap, retval, 0);
  560 }
  561 
  562 int
  563 linux_sys_lstat(p, v, retval)
  564         struct proc *p;
  565         void *v;
  566         register_t *retval;
  567 {
  568         struct linux_sys_lstat_args /* {
  569                 syscallarg(char *) path;
  570                 syscallarg(struct linux_stat *) sp;
  571         } */ *uap = v;
  572 
  573         return linux_stat1(p, uap, retval, 1);
  574 }
  575 
  576 /*
  577  * The following syscalls are mostly here because of the alternate path check.
  578  */
  579 int
  580 linux_sys_access(p, v, retval)
  581         struct proc *p;
  582         void *v;
  583         register_t *retval;
  584 {
  585         struct linux_sys_access_args /* {
  586                 syscallarg(char *) path;
  587                 syscallarg(int) flags;
  588         } */ *uap = v;
  589         caddr_t sg = stackgap_init(p->p_emul);
  590 
  591         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  592 
  593         return sys_access(p, uap, retval);
  594 }
  595 
  596 int
  597 linux_sys_unlink(p, v, retval)
  598         struct proc *p;
  599         void *v;
  600         register_t *retval;
  601 
  602 {
  603         struct linux_sys_unlink_args /* {
  604                 syscallarg(char *) path;
  605         } */ *uap = v;
  606         caddr_t sg = stackgap_init(p->p_emul);
  607 
  608         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  609 
  610         return sys_unlink(p, uap, retval);
  611 }
  612 
  613 int
  614 linux_sys_chdir(p, v, retval)
  615         struct proc *p;
  616         void *v;
  617         register_t *retval;
  618 {
  619         struct linux_sys_chdir_args /* {
  620                 syscallarg(char *) path;
  621         } */ *uap = v;
  622         caddr_t sg = stackgap_init(p->p_emul);
  623 
  624         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  625 
  626         return sys_chdir(p, uap, retval);
  627 }
  628 
  629 int
  630 linux_sys_mknod(p, v, retval)
  631         struct proc *p;
  632         void *v;
  633         register_t *retval;
  634 {
  635         struct linux_sys_mknod_args /* {
  636                 syscallarg(char *) path;
  637                 syscallarg(int) mode;
  638                 syscallarg(int) dev;
  639         } */ *uap = v;
  640         caddr_t sg = stackgap_init(p->p_emul);
  641         struct sys_mkfifo_args bma;
  642 
  643         LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  644 
  645         /*
  646          * BSD handles FIFOs separately
  647          */
  648         if (S_ISFIFO(SCARG(uap, mode))) {
  649                 SCARG(&bma, path) = SCARG(uap, path);
  650                 SCARG(&bma, mode) = SCARG(uap, mode);
  651                 return sys_mkfifo(p, uap, retval);
  652         } else
  653                 return sys_mknod(p, uap, retval);
  654 }
  655 
  656 int
  657 linux_sys_chmod(p, v, retval)
  658         struct proc *p;
  659         void *v;
  660         register_t *retval;
  661 {
  662         struct linux_sys_chmod_args /* {
  663                 syscallarg(char *) path;
  664                 syscallarg(int) mode;
  665         } */ *uap = v;
  666         caddr_t sg = stackgap_init(p->p_emul);
  667 
  668         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  669 
  670         return sys_chmod(p, uap, retval);
  671 }
  672 
  673 int
  674 linux_sys_chown16(p, v, retval)
  675         struct proc *p;
  676         void *v;
  677         register_t *retval;
  678 {
  679         struct linux_sys_chown16_args /* {
  680                 syscallarg(char *) path;
  681                 syscallarg(int) uid;
  682                 syscallarg(int) gid;
  683         } */ *uap = v;
  684         struct sys_chown_args bca;
  685         caddr_t sg = stackgap_init(p->p_emul);
  686 
  687         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  688 
  689         SCARG(&bca, path) = SCARG(uap, path);
  690         SCARG(&bca, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
  691                 (uid_t)-1 : SCARG(uap, uid);
  692         SCARG(&bca, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
  693                 (gid_t)-1 : SCARG(uap, gid);
  694         
  695         return sys_chown(p, &bca, retval);
  696 }
  697 
  698 int
  699 linux_sys_fchown16(p, v, retval)
  700         struct proc *p;
  701         void *v;
  702         register_t *retval;
  703 {
  704         struct linux_sys_fchown16_args /* {
  705                 syscallarg(int) fd;
  706                 syscallarg(int) uid;
  707                 syscallarg(int) gid;
  708         } */ *uap = v;
  709         struct sys_fchown_args bfa;
  710 
  711         SCARG(&bfa, fd) = SCARG(uap, fd);
  712         SCARG(&bfa, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
  713                 (uid_t)-1 : SCARG(uap, uid);
  714         SCARG(&bfa, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
  715                 (gid_t)-1 : SCARG(uap, gid);
  716         
  717         return sys_fchown(p, &bfa, retval);
  718 }
  719 
  720 int
  721 linux_sys_lchown16(p, v, retval)
  722         struct proc *p;
  723         void *v;
  724         register_t *retval;
  725 {
  726         struct linux_sys_lchown16_args /* {
  727                 syscallarg(char *) path;
  728                 syscallarg(int) uid;
  729                 syscallarg(int) gid;
  730         } */ *uap = v;
  731         struct sys_lchown_args bla;
  732 
  733         SCARG(&bla, path) = SCARG(uap, path);
  734         SCARG(&bla, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
  735                 (uid_t)-1 : SCARG(uap, uid);
  736         SCARG(&bla, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
  737                 (gid_t)-1 : SCARG(uap, gid);
  738 
  739         return sys_lchown(p, &bla, retval);
  740 }
  741 
  742 int
  743 linux_sys_rename(p, v, retval)
  744         struct proc *p;
  745         void *v;
  746         register_t *retval;
  747 {
  748         struct linux_sys_rename_args /* {
  749                 syscallarg(char *) from;
  750                 syscallarg(char *) to;
  751         } */ *uap = v;
  752         caddr_t sg = stackgap_init(p->p_emul);
  753 
  754         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
  755         LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
  756 
  757         return sys_rename(p, uap, retval);
  758 }
  759 
  760 int
  761 linux_sys_mkdir(p, v, retval)
  762         struct proc *p;
  763         void *v;
  764         register_t *retval;
  765 {
  766         struct linux_sys_mkdir_args /* {
  767                 syscallarg(char *) path;
  768                 syscallarg(int) mode;
  769         } */ *uap = v;
  770         caddr_t sg = stackgap_init(p->p_emul);
  771 
  772         LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  773 
  774         return sys_mkdir(p, uap, retval);
  775 }
  776 
  777 int
  778 linux_sys_rmdir(p, v, retval)
  779         struct proc *p;
  780         void *v;
  781         register_t *retval;
  782 {
  783         struct linux_sys_rmdir_args /* {
  784                 syscallarg(char *) path;
  785         } */ *uap = v;
  786         caddr_t sg = stackgap_init(p->p_emul);
  787 
  788         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  789 
  790         return sys_rmdir(p, uap, retval);
  791 }
  792 
  793 int
  794 linux_sys_symlink(p, v, retval)
  795         struct proc *p;
  796         void *v;
  797         register_t *retval;
  798 {
  799         struct linux_sys_symlink_args /* {
  800                 syscallarg(char *) path;
  801                 syscallarg(char *) to;
  802         } */ *uap = v;
  803         caddr_t sg = stackgap_init(p->p_emul);
  804 
  805         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  806         LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
  807 
  808         return sys_symlink(p, uap, retval);
  809 }
  810 
  811 int
  812 linux_sys_readlink(p, v, retval)
  813         struct proc *p;
  814         void *v;
  815         register_t *retval;
  816 {
  817         struct linux_sys_readlink_args /* {
  818                 syscallarg(char *) name;
  819                 syscallarg(char *) buf;
  820                 syscallarg(int) count;
  821         } */ *uap = v;
  822         caddr_t sg = stackgap_init(p->p_emul);
  823 
  824         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, name));
  825 
  826         return sys_readlink(p, uap, retval);
  827 }
  828 
  829 int
  830 linux_sys_truncate(p, v, retval)
  831         struct proc *p;
  832         void *v;
  833         register_t *retval;
  834 {
  835         struct linux_sys_truncate_args /* {
  836                 syscallarg(char *) path;
  837                 syscallarg(long) length;
  838         } */ *uap = v;
  839         caddr_t sg = stackgap_init(p->p_emul);
  840 
  841         LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  842 
  843         return compat_43_sys_truncate(p, uap, retval);
  844 }
  845 
  846 /*
  847  * This is just fsync() for now (just as it is in the Linux kernel)
  848  */
  849 int
  850 linux_sys_fdatasync(p, v, retval)
  851         struct proc *p;
  852         void *v;
  853         register_t *retval;
  854 {
  855         struct linux_sys_fdatasync_args /* {
  856                 syscallarg(int) fd;
  857         } */ *uap = v;
  858         return sys_fsync(p, uap, retval);
  859 }
  860 
  861 /*
  862  * pread(2).
  863  */
  864 int
  865 linux_sys_pread(p, v, retval)
  866         struct proc *p;
  867         void *v;
  868         register_t *retval;
  869 {
  870         struct linux_sys_pread_args /* {
  871                 syscallarg(int) fd;
  872                 syscallarg(void *) buf;
  873                 syscallarg(size_t) nbyte;
  874                 syscallarg(linux_off_t) offset;
  875         } */ *uap = v;
  876         struct sys_pread_args pra;
  877         
  878         SCARG(&pra, fd) = SCARG(uap, fd);
  879         SCARG(&pra, buf) = SCARG(uap, buf);
  880         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  881         SCARG(&pra, offset) = SCARG(uap, offset);
  882         
  883         return sys_pread(p, &pra, retval);
  884 }
  885 
  886 /*
  887  * pwrite(2).
  888  */
  889 int
  890 linux_sys_pwrite(p, v, retval)
  891         struct proc *p;
  892         void *v;
  893         register_t *retval;
  894 {
  895         struct linux_sys_pwrite_args /* {
  896                 syscallarg(int) fd;
  897                 syscallarg(char *) buf;
  898                 syscallarg(size_t) nbyte;
  899                 syscallarg(linux_off_t) offset;
  900         } */ *uap = v;
  901         struct sys_pwrite_args pra;
  902 
  903         SCARG(&pra, fd) = SCARG(uap, fd);
  904         SCARG(&pra, buf) = SCARG(uap, buf);
  905         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  906         SCARG(&pra, offset) = SCARG(uap, offset);
  907 
  908         return sys_pwrite(p, &pra, retval);
  909 }

/* [<][>][^][v][top][bottom][index][help] */