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/linux32/common/linux32_unistd.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: linux32_unistd.c,v 1.24 2008/10/03 22:39:36 njoly Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2006 Emmanuel Dreyfus, 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 Emmanuel Dreyfus
   17  * 4. The name of the author may not be used to endorse or promote 
   18  *    products derived from this software without specific prior written 
   19  *    permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 
   22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
   23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 
   25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   31  * POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 
   36 __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.24 2008/10/03 22:39:36 njoly Exp $");
   37 
   38 #include <sys/types.h>
   39 #include <sys/param.h>
   40 #include <sys/fstypes.h>
   41 #include <sys/signal.h>
   42 #include <sys/dirent.h>
   43 #include <sys/kernel.h>
   44 #include <sys/fcntl.h>
   45 #include <sys/select.h>
   46 #include <sys/proc.h>
   47 #include <sys/ucred.h>
   48 #include <sys/swap.h>
   49 
   50 #include <machine/types.h>
   51 
   52 #include <sys/syscallargs.h>
   53 
   54 #include <compat/netbsd32/netbsd32.h>
   55 #include <compat/netbsd32/netbsd32_conv.h>
   56 
   57 #include <compat/linux/common/linux_types.h>
   58 #include <compat/linux/common/linux_signal.h>
   59 #include <compat/linux/common/linux_machdep.h>
   60 #include <compat/linux/common/linux_misc.h>
   61 #include <compat/linux/common/linux_oldolduname.h>
   62 #include <compat/linux/linux_syscallargs.h>
   63 
   64 #include <compat/linux32/common/linux32_types.h>
   65 #include <compat/linux32/common/linux32_signal.h>
   66 #include <compat/linux32/common/linux32_machdep.h>
   67 #include <compat/linux32/common/linux32_sysctl.h>
   68 #include <compat/linux32/common/linux32_socketcall.h>
   69 #include <compat/linux32/linux32_syscallargs.h>
   70 
   71 static int linux32_select1(struct lwp *, register_t *, 
   72     int, fd_set *, fd_set *, fd_set *, struct timeval *);
   73 
   74 int
   75 linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval)
   76 {
   77         /* {
   78                 syscallarg(netbsd32_charp) nsize;
   79         } */
   80         struct linux_sys_brk_args ua;
   81 
   82         NETBSD32TOP_UAP(nsize, char);
   83         return linux_sys_brk(l, &ua, retval);
   84 }
   85 
   86 int
   87 linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval)
   88 {
   89         /* {
   90                 syscallcarg(int) fd;
   91                 syscallarg(u_int32_t) ohigh;
   92                 syscallarg(u_int32_t) olow;
   93                 syscallarg(netbsd32_caddr_t) res;
   94                 syscallcarg(int) whence;
   95         } */
   96         struct linux_sys_llseek_args ua;
   97 
   98         NETBSD32TO64_UAP(fd);
   99         NETBSD32TO64_UAP(ohigh);
  100         NETBSD32TO64_UAP(olow);
  101         NETBSD32TOP_UAP(res, char);
  102         NETBSD32TO64_UAP(whence);
  103 
  104         return linux_sys_llseek(l, &ua, retval);
  105 }
  106 
  107 int
  108 linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval)
  109 {
  110         /* {
  111                 syscallarg(int) nfds;
  112                 syscallarg(netbsd32_fd_setp_t) readfds;
  113                 syscallarg(netbsd32_fd_setp_t) writefds;
  114                 syscallarg(netbsd32_fd_setp_t) exceptfds;
  115                 syscallarg(netbsd32_timevalp_t) timeout;
  116         } */
  117 
  118         return linux32_select1(l, retval, SCARG(uap, nfds), 
  119             SCARG_P32(uap, readfds),
  120             SCARG_P32(uap, writefds), 
  121             SCARG_P32(uap, exceptfds), 
  122             SCARG_P32(uap, timeout));
  123 }
  124 
  125 int
  126 linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval)
  127 {
  128         /* {
  129                 syscallarg(linux32_oldselectp_t) lsp;
  130         } */
  131         struct linux32_oldselect lsp32;
  132         int error;
  133 
  134         if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0)
  135                 return error;
  136 
  137         return linux32_select1(l, retval, lsp32.nfds, 
  138              NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds),
  139              NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout));
  140 }
  141 
  142 static int
  143 linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout)
  144         struct lwp *l;
  145         register_t *retval;
  146         int nfds;
  147         fd_set *readfds, *writefds, *exceptfds;
  148         struct timeval *timeout;
  149 {   
  150         struct timeval tv0, tv1, utv, *tv = NULL;
  151         struct netbsd32_timeval utv32;
  152         int error;
  153 
  154         timerclear(&utv); /* XXX GCC4 */
  155 
  156         /*
  157          * Store current time for computation of the amount of
  158          * time left.
  159          */
  160         if (timeout) {
  161                 if ((error = copyin(timeout, &utv32, sizeof(utv32))))
  162                         return error;
  163 
  164                 netbsd32_to_timeval(&utv32, &utv);
  165 
  166                 if (itimerfix(&utv)) {
  167                         /*
  168                          * The timeval was invalid.  Convert it to something
  169                          * valid that will act as it does under Linux.
  170                          */
  171                         utv.tv_sec += utv.tv_usec / 1000000;
  172                         utv.tv_usec %= 1000000;
  173                         if (utv.tv_usec < 0) {
  174                                 utv.tv_sec -= 1;
  175                                 utv.tv_usec += 1000000;
  176                         }
  177                         if (utv.tv_sec < 0)
  178                                 timerclear(&utv);
  179                 }
  180                 microtime(&tv0);
  181                 tv = &utv;
  182         }
  183 
  184         error = selcommon(l, retval, nfds, 
  185             readfds, writefds, exceptfds, tv, NULL);
  186 
  187         if (error) {
  188                 /*
  189                  * See fs/select.c in the Linux kernel.  Without this,
  190                  * Maelstrom doesn't work.
  191                  */
  192                 if (error == ERESTART)
  193                         error = EINTR;
  194                 return error;
  195         }
  196 
  197         if (timeout) {
  198                 if (*retval) {
  199                         /*
  200                          * Compute how much time was left of the timeout,
  201                          * by subtracting the current time and the time
  202                          * before we started the call, and subtracting
  203                          * that result from the user-supplied value.
  204                          */
  205                         microtime(&tv1);
  206                         timersub(&tv1, &tv0, &tv1);
  207                         timersub(&utv, &tv1, &utv);
  208                         if (utv.tv_sec < 0)
  209                                 timerclear(&utv);
  210                 } else {
  211                         timerclear(&utv);
  212                 }
  213                 
  214                 netbsd32_from_timeval(&utv, &utv32);
  215 
  216                 if ((error = copyout(&utv32, timeout, sizeof(utv32))))
  217                         return error;
  218         }
  219 
  220         return 0;
  221 }
  222 
  223 int
  224 linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, register_t *retval)
  225 {
  226         /* {
  227                 syscallarg(netbsd32_intp) fd;
  228         } */
  229         int error;
  230         int pfds[2];
  231 
  232         if ((error = sys_pipe(l, 0, retval)))
  233                 return error;
  234 
  235         pfds[0] = (int)retval[0];
  236         pfds[1] = (int)retval[1];
  237 
  238         if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0)
  239                 return error;
  240 
  241         retval[0] = 0;
  242         retval[1] = 0;
  243 
  244         return 0;
  245 }
  246 
  247 
  248 int
  249 linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval)
  250 {
  251         /* {
  252                 syscallarg(const netbsd32_charp) path;
  253         } */
  254         struct linux_sys_unlink_args ua;
  255 
  256         NETBSD32TOP_UAP(path, const char);
  257         
  258         return linux_sys_unlink(l, &ua, retval);
  259 }
  260 
  261 int
  262 linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval)
  263 {
  264         /* {
  265                 syscallarg(const netbsd32_charp) path;
  266                 syscallarg(int) mode;
  267         } */
  268         struct sys_open_args ua;
  269 
  270         NETBSD32TOP_UAP(path, const char);
  271         SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY;
  272         NETBSD32TO64_UAP(mode);
  273 
  274         return sys_open(l, &ua, retval);
  275 }
  276 
  277 int
  278 linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval)
  279 {
  280         /* {
  281                 syscallarg(const netbsd32_charp) path;
  282                 syscallarg(int) mode;
  283                 syscallarg(int) dev;
  284         } */
  285         struct linux_sys_mknod_args ua;
  286 
  287         NETBSD32TOP_UAP(path, const char);
  288         NETBSD32TO64_UAP(mode);
  289         NETBSD32TO64_UAP(dev);
  290 
  291         return linux_sys_mknod(l, &ua, retval);
  292 }
  293 
  294 int
  295 linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval)
  296 {
  297 #if 0
  298         /* {
  299                 syscallarg(const netbsd32_charp) nsize;
  300         } */
  301 #endif
  302 
  303         return ENOSYS;
  304 }
  305 
  306 int
  307 linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval)
  308 {
  309         /* {
  310                 syscallarg(const netbsd32_charp) name;
  311         } */
  312         struct sys_swapctl_args ua;
  313 
  314         SCARG(&ua, cmd) = SWAP_ON;
  315         SCARG(&ua, arg) = SCARG_P32(uap, name);
  316         SCARG(&ua, misc) = 0;   /* priority */
  317         return (sys_swapctl(l, &ua, retval));
  318 }
  319 
  320 int
  321 linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval)
  322 {
  323         /* {
  324                 syscallarg(const netbsd32_charp) path;
  325         } */
  326         struct sys_swapctl_args ua;
  327 
  328         SCARG(&ua, cmd) = SWAP_OFF;
  329         SCARG(&ua, arg) = SCARG_P32(uap, path);
  330         SCARG(&ua, misc) = 0;   /* priority */
  331         return (sys_swapctl(l, &ua, retval));
  332 }
  333 
  334 
  335 int
  336 linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval)
  337 {
  338         /* {
  339                 syscallarg(int) magic1;
  340                 syscallarg(int) magic2;
  341                 syscallarg(int) cmd;
  342                 syscallarg(netbsd32_voidp) arg;
  343         } */
  344         struct linux_sys_reboot_args ua;
  345 
  346         NETBSD32TO64_UAP(magic1);
  347         NETBSD32TO64_UAP(magic2);
  348         NETBSD32TO64_UAP(cmd);
  349         NETBSD32TOP_UAP(arg, void);
  350         
  351         return linux_sys_reboot(l, &ua, retval);
  352 }
  353 
  354 int
  355 linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval)
  356 {
  357         /* {
  358                 syscallarg(uid_t) ruid;
  359                 syscallarg(uid_t) euid;
  360                 syscallarg(uid_t) suid;
  361         } */
  362         struct linux_sys_setresuid_args ua;
  363 
  364         SCARG(&ua, ruid) = (SCARG(uap, ruid) == -1) ? -1 : SCARG(uap, ruid);
  365         SCARG(&ua, euid) = (SCARG(uap, euid) == -1) ? -1 : SCARG(uap, euid);
  366         SCARG(&ua, suid) = (SCARG(uap, suid) == -1) ? -1 : SCARG(uap, suid);
  367 
  368         return linux_sys_setresuid(l, &ua, retval);
  369 }
  370 
  371 int
  372 linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval)
  373 {
  374         /* {
  375                 syscallarg(gid_t) rgid;
  376                 syscallarg(gid_t) egid;
  377                 syscallarg(gid_t) sgid;
  378         } */
  379         struct linux_sys_setresgid_args ua;
  380 
  381         SCARG(&ua, rgid) = (SCARG(uap, rgid) == -1) ? -1 : SCARG(uap, rgid);
  382         SCARG(&ua, egid) = (SCARG(uap, egid) == -1) ? -1 : SCARG(uap, egid);
  383         SCARG(&ua, sgid) = (SCARG(uap, sgid) == -1) ? -1 : SCARG(uap, sgid);
  384 
  385         return linux_sys_setresgid(l, &ua, retval);
  386 }
  387 
  388 int
  389 linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval)
  390 {
  391         /* {
  392                 syscallarg(int) incr;
  393         } */
  394         struct proc *p = l->l_proc;
  395         struct sys_setpriority_args bsa;
  396 
  397         SCARG(&bsa, which) = PRIO_PROCESS;
  398         SCARG(&bsa, who) = 0;
  399         SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
  400 
  401         return sys_setpriority(l, &bsa, retval);
  402 }
  403 
  404 int
  405 linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval)
  406 {
  407         /* {
  408                 syscallarg(unsigned int) secs;
  409         } */
  410         struct linux_sys_alarm_args ua;
  411 
  412         NETBSD32TO64_UAP(secs);
  413 
  414         return linux_sys_alarm(l, &ua, retval);
  415 }
  416 
  417 int
  418 linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval)
  419 {
  420         /* {
  421                 syscallarg(int) fd;
  422         } */
  423         struct linux_sys_fdatasync_args ua;
  424 
  425         NETBSD32TO64_UAP(fd);
  426 
  427         return linux_sys_fdatasync(l, &ua, retval);
  428 }
  429 
  430 int
  431 linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval)
  432 {
  433         /* {
  434                 syscallarg(uid_t) uid;
  435         } */
  436         struct linux_sys_setfsuid_args ua;
  437 
  438         NETBSD32TO64_UAP(uid);
  439 
  440         return linux_sys_setfsuid(l, &ua, retval);
  441 }
  442 
  443 int
  444 linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval)
  445 {
  446         /* {
  447                 syscallarg(gid_t) gid;
  448         } */
  449         struct linux_sys_setfsgid_args ua;
  450 
  451         NETBSD32TO64_UAP(gid);
  452 
  453         return linux_sys_setfsgid(l, &ua, retval);
  454 }
  455 
  456 /*
  457  * pread(2).
  458  */
  459 int
  460 linux32_sys_pread(struct lwp *l,
  461     const struct linux32_sys_pread_args *uap, register_t *retval)
  462 {
  463         /* {
  464                 syscallarg(int) fd;
  465                 syscallarg(netbsd32_voidp) buf;
  466                 syscallarg(netbsd32_size_t) nbyte;
  467                 syscallarg(linux32_off_t) offset;
  468         } */
  469         struct sys_pread_args pra;
  470 
  471         SCARG(&pra, fd) = SCARG(uap, fd);
  472         SCARG(&pra, buf) = SCARG_P32(uap, buf);
  473         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  474         SCARG(&pra, offset) = SCARG(uap, offset);
  475 
  476         return sys_pread(l, &pra, retval);
  477 }
  478 
  479 /*
  480  * pwrite(2).
  481  */
  482 int
  483 linux32_sys_pwrite(struct lwp *l,
  484     const struct linux32_sys_pwrite_args *uap, register_t *retval)
  485 {
  486         /* {
  487                 syscallarg(int) fd;
  488                 syscallarg(const netbsd32_voidp) buf;
  489                 syscallarg(netbsd32_size_t) nbyte;
  490                 syscallarg(linux32_off_t) offset;
  491         } */
  492         struct sys_pwrite_args pra;
  493 
  494         SCARG(&pra, fd) = SCARG(uap, fd);
  495         SCARG(&pra, buf) = SCARG_P32(uap, buf);
  496         SCARG(&pra, nbyte) = SCARG(uap, nbyte);
  497         SCARG(&pra, offset) = SCARG(uap, offset);
  498 
  499         return sys_pwrite(l, &pra, retval);
  500 }
  501 

Cache object: 6a94d9a50ddcef83da4b86f98e926ed9


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