root/compat/hpux/hpux_compat.c

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

DEFINITIONS

This source file includes following definitions.
  1. hpux_sys_fork
  2. hpux_sys_vfork
  3. hpux_sys_wait3
  4. hpux_sys_wait
  5. hpux_sys_waitpid
  6. hpux_sys_read
  7. hpux_sys_write
  8. hpux_sys_readv
  9. hpux_sys_writev
  10. hpux_sys_utssys
  11. hpux_sys_sysconf
  12. hpux_sys_ulimit
  13. hpux_sys_rtprio
  14. hpux_sys_ptrace
  15. hpux_sys_shmctl
  16. hpux_sys_nshmctl
  17. hpux_shmctl1
  18. hpux_sys_mmap
  19. hpuxtobsdioctl
  20. hpux_sys_ioctl
  21. hpux_sys_getpgrp2
  22. hpux_sys_setpgrp2
  23. hpux_sys_getrlimit
  24. hpux_sys_setrlimit
  25. hpux_sys_lockf
  26. hpux_sys_getaccess
  27. hpux_sys_setpgrp_6x
  28. hpux_sys_time_6x
  29. hpux_sys_stime_6x
  30. hpux_sys_ftime_6x
  31. hpux_sys_alarm_6x
  32. hpux_sys_nice_6x
  33. hpux_sys_times_6x
  34. hpux_scale
  35. hpux_sys_utime_6x
  36. hpux_sys_pause_6x

    1 /*      $OpenBSD: hpux_compat.c,v 1.28 2004/07/09 21:33:44 mickey Exp $ */
    2 /*      $NetBSD: hpux_compat.c,v 1.35 1997/05/08 16:19:48 mycroft Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1988 University of Utah.
    6  * Copyright (c) 1990, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  *
    9  * This code is derived from software contributed to Berkeley by
   10  * the Systems Programming Group of the University of Utah Computer
   11  * Science Department.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * from: Utah $Hdr: hpux_compat.c 1.64 93/08/05$
   38  *
   39  *      @(#)hpux_compat.c       8.4 (Berkeley) 2/13/94
   40  */
   41 
   42 /*
   43  * Various HP-UX compatibility routines
   44  */
   45 
   46 #ifndef COMPAT_43
   47 #define COMPAT_43
   48 #endif
   49 
   50 #include <sys/param.h>
   51 #include <sys/systm.h>
   52 #include <sys/signalvar.h>
   53 #include <sys/kernel.h>
   54 #include <sys/filedesc.h>
   55 #include <sys/proc.h>
   56 #include <sys/buf.h>
   57 #include <sys/wait.h>
   58 #include <sys/file.h>
   59 #include <sys/namei.h>
   60 #include <sys/vnode.h>
   61 #include <sys/ioctl.h>
   62 #include <sys/ptrace.h>
   63 #include <sys/stat.h>
   64 #include <sys/syslog.h>
   65 #include <sys/malloc.h>
   66 #include <sys/mount.h>
   67 #include <sys/ipc.h>
   68 #include <sys/user.h>
   69 #include <sys/mman.h>
   70 
   71 #include <machine/cpu.h>
   72 #include <machine/reg.h>
   73 #include <machine/psl.h>
   74 #include <machine/vmparam.h>
   75 
   76 #include <sys/syscallargs.h>
   77 
   78 #include <compat/hpux/hpux.h>
   79 #include <compat/hpux/hpux_sig.h>
   80 #include <compat/hpux/hpux_util.h>
   81 #include <compat/hpux/hpux_termio.h>
   82 #include <compat/hpux/hpux_syscall.h>
   83 #include <compat/hpux/hpux_syscallargs.h>
   84 
   85 #include <machine/hpux_machdep.h>
   86 
   87 #ifdef DEBUG
   88 int unimpresponse = 0;
   89 #endif
   90 
   91 #define NERR    83
   92 #define BERR    1000
   93 
   94 /* indexed by BSD errno */
   95 int bsdtohpuxerrnomap[NERR] = {
   96 /*00*/    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
   97 /*10*/   10,  45,  12,  13,  14,  15,  16,  17,  18,  19,
   98 /*20*/   20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
   99 /*30*/   30,  31,  32,  33,  34, 246, 245, 244, 216, 217,
  100 /*40*/  218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
  101 /*50*/  228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
  102 /*60*/  238, 239, 249, 248, 241, 242, 247,BERR,BERR,BERR,
  103 /*70*/   70,  71,BERR,BERR,BERR,BERR,BERR,  46, 251,BERR,
  104 /*80*/ BERR,BERR,  11
  105 };
  106 
  107 extern char sigcode[], esigcode[];
  108 extern struct sysent hpux_sysent[];
  109 extern char *hpux_syscallnames[];
  110 
  111 int     hpux_shmctl1(struct proc *, struct hpux_sys_shmctl_args *,
  112             register_t *, int);
  113 int     hpuxtobsdioctl(u_long);
  114 
  115 static int      hpux_scale(struct timeval *);
  116 
  117 /*
  118  * HP-UX fork and vfork need to map the EAGAIN return value appropriately.
  119  */
  120 int
  121 hpux_sys_fork(p, v, retval)
  122         struct proc *p;
  123         void *v;
  124         register_t *retval;
  125 {
  126         /* struct hpux_sys_fork_args *uap = v; */
  127         int error;
  128 
  129         error = sys_fork(p, v, retval);
  130         if (error == EAGAIN)
  131                 error = OEAGAIN;
  132         return (error);
  133 }
  134 
  135 int
  136 hpux_sys_vfork(p, v, retval)
  137         struct proc *p;
  138         void *v;
  139         register_t *retval;
  140 {
  141         /* struct hpux_sys_vfork_args *uap = v; */
  142         int error;
  143 
  144         error = sys_vfork(p, v, retval);
  145         if (error == EAGAIN)
  146                 error = OEAGAIN;
  147         return (error);
  148 }
  149 
  150 /*
  151  * HP-UX versions of wait and wait3 actually pass the parameters
  152  * (status pointer, options, rusage) into the kernel rather than
  153  * handling it in the C library stub.  We also need to map any
  154  * termination signal from BSD to HP-UX.
  155  */
  156 int
  157 hpux_sys_wait3(p, v, retval)
  158         struct proc *p;
  159         void *v;
  160         register_t *retval;
  161 {
  162         struct hpux_sys_wait3_args *uap = v;
  163 
  164         /* rusage pointer must be zero */
  165         if (SCARG(uap, rusage))
  166                 return (EINVAL);
  167 #ifdef m68k
  168         p->p_md.md_regs[PS] = PSL_ALLCC;
  169         p->p_md.md_regs[R0] = SCARG(uap, options);
  170         p->p_md.md_regs[R1] = SCARG(uap, rusage);
  171 #endif
  172 
  173         return (hpux_sys_wait(p, uap, retval));
  174 }
  175 
  176 int
  177 hpux_sys_wait(p, v, retval)
  178         struct proc *p;
  179         void *v;
  180         register_t *retval;
  181 {
  182         struct hpux_sys_wait_args *uap = v;
  183         struct sys_wait4_args w4;
  184         int error;
  185         int sig;
  186         size_t sz = sizeof(*SCARG(&w4, status));
  187         int status;
  188 
  189         SCARG(&w4, rusage) = NULL;
  190         SCARG(&w4, options) = 0;
  191 
  192         if (SCARG(uap, status) == NULL) {
  193                 caddr_t sg = stackgap_init(p->p_emul);
  194                 SCARG(&w4, status) = stackgap_alloc(&sg, sz);
  195         }
  196         else
  197                 SCARG(&w4, status) = SCARG(uap, status);
  198 
  199         SCARG(&w4, pid) = WAIT_ANY;
  200 
  201         error = sys_wait4(p, &w4, retval);
  202         /*
  203          * HP-UX wait always returns EINTR when interrupted by a signal
  204          * (well, unless its emulating a BSD process, but we don't bother...)
  205          */
  206         if (error == ERESTART)
  207                 error = EINTR;
  208         if (error)
  209                 return error;
  210 
  211         if ((error = copyin(SCARG(&w4, status), &status, sizeof(status))) != 0)
  212                 return error;
  213 
  214         sig = status & 0xFF;
  215         if (sig == WSTOPPED) {
  216                 sig = (status >> 8) & 0xFF;
  217                 retval[1] = (bsdtohpuxsig(sig) << 8) | WSTOPPED;
  218         } else if (sig)
  219                 retval[1] = (status & 0xFF00) |
  220                         bsdtohpuxsig(sig & 0x7F) | (sig & 0x80);
  221 
  222         if (SCARG(uap, status) == NULL)
  223                 return error;
  224         else
  225                 return copyout(&retval[1], 
  226                                SCARG(uap, status), sizeof(retval[1]));
  227 }
  228 
  229 int
  230 hpux_sys_waitpid(p, v, retval)
  231         struct proc *p;
  232         void *v;
  233         register_t *retval;
  234 {
  235         struct hpux_sys_waitpid_args *uap = v;
  236         int rv, sig, xstat, error;
  237 
  238         SCARG(uap, rusage) = 0;
  239         error = sys_wait4(p, uap, retval);
  240         /*
  241          * HP-UX wait always returns EINTR when interrupted by a signal
  242          * (well, unless its emulating a BSD process, but we don't bother...)
  243          */
  244         if (error == ERESTART)
  245                 error = EINTR;
  246         if (error)
  247                 return (error);
  248 
  249         if (SCARG(uap, status)) {
  250                 /*
  251                  * Wait4 already wrote the status out to user space,
  252                  * pull it back, change the signal portion, and write
  253                  * it back out.
  254                  */
  255                 if ((error = copyin((caddr_t)SCARG(uap, status), &rv,
  256                     sizeof(int))) != 0)
  257                         return error;
  258 
  259                 if (WIFSTOPPED(rv)) {
  260                         sig = WSTOPSIG(rv);
  261                         rv = W_STOPCODE(bsdtohpuxsig(sig));
  262                 } else if (WIFSIGNALED(rv)) {
  263                         sig = WTERMSIG(rv);
  264                         xstat = WEXITSTATUS(rv);
  265                         rv = W_EXITCODE(xstat, bsdtohpuxsig(sig)) |
  266                                 WCOREDUMP(rv);
  267                 }
  268                 error = copyout(&rv, (caddr_t)SCARG(uap, status), sizeof(int));
  269         }
  270         return (error);
  271 }
  272 
  273 /*
  274  * Read and write calls.  Same as BSD except for non-blocking behavior.
  275  * There are three types of non-blocking reads/writes in HP-UX checked
  276  * in the following order:
  277  *
  278  *      O_NONBLOCK: return -1 and errno == EAGAIN
  279  *      O_NDELAY:   return 0
  280  *      FIOSNBIO:   return -1 and errno == EWOULDBLOCK
  281  */
  282 int
  283 hpux_sys_read(p, v, retval)
  284         struct proc *p;
  285         void *v;
  286         register_t *retval;
  287 {
  288         struct hpux_sys_read_args *uap = v;
  289         int error;
  290 
  291         error = sys_read(p, (struct sys_read_args *) uap, retval);
  292         if (error == EWOULDBLOCK) {
  293                 char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
  294 
  295                 if (*fp & HPUX_UF_NONBLOCK_ON) {
  296                         *retval = -1;
  297                         error = OEAGAIN;
  298                 } else if (*fp & HPUX_UF_FNDELAY_ON) {
  299                         *retval = 0;
  300                         error = 0;
  301                 }
  302         }
  303         return (error);
  304 }
  305 
  306 int
  307 hpux_sys_write(p, v, retval)
  308         struct proc *p;
  309         void *v;
  310         register_t *retval;
  311 {
  312         struct hpux_sys_write_args *uap = v;
  313         int error;
  314 
  315         error = sys_write(p, (struct sys_write_args *) uap, retval);
  316         if (error == EWOULDBLOCK) {
  317                 char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
  318 
  319                 if (*fp & HPUX_UF_NONBLOCK_ON) {
  320                         *retval = -1;
  321                         error = OEAGAIN;
  322                 } else if (*fp & HPUX_UF_FNDELAY_ON) {
  323                         *retval = 0;
  324                         error = 0;
  325                 }
  326         }
  327         return (error);
  328 }
  329 
  330 int
  331 hpux_sys_readv(p, v, retval)
  332         struct proc *p;
  333         void *v;
  334         register_t *retval;
  335 {
  336         struct hpux_sys_readv_args *uap = v;
  337         int error;
  338 
  339         error = sys_readv(p, (struct sys_readv_args *) uap, retval);
  340         if (error == EWOULDBLOCK) {
  341                 char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
  342 
  343                 if (*fp & HPUX_UF_NONBLOCK_ON) {
  344                         *retval = -1;
  345                         error = OEAGAIN;
  346                 } else if (*fp & HPUX_UF_FNDELAY_ON) {
  347                         *retval = 0;
  348                         error = 0;
  349                 }
  350         }
  351         return (error);
  352 }
  353 
  354 int
  355 hpux_sys_writev(p, v, retval)
  356         struct proc *p;
  357         void *v;
  358         register_t *retval;
  359 {
  360         struct hpux_sys_writev_args *uap = v;
  361         int error;
  362 
  363         error = sys_writev(p, (struct sys_writev_args *) uap, retval);
  364         if (error == EWOULDBLOCK) {
  365                 char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
  366 
  367                 if (*fp & HPUX_UF_NONBLOCK_ON) {
  368                         *retval = -1;
  369                         error = OEAGAIN;
  370                 } else if (*fp & HPUX_UF_FNDELAY_ON) {
  371                         *retval = 0;
  372                         error = 0;
  373                 }
  374         }
  375         return (error);
  376 }
  377 
  378 int
  379 hpux_sys_utssys(p, v, retval)
  380         struct proc *p;
  381         void *v;
  382         register_t *retval;
  383 {
  384         struct hpux_sys_utssys_args *uap = v;
  385         int i;
  386         int error;
  387         struct hpux_utsname     ut;
  388         extern char hostname[], machine[];
  389 
  390         switch (SCARG(uap, request)) {
  391         /* uname */
  392         case 0:
  393                 bzero(&ut, sizeof(ut));
  394 
  395                 strlcpy(ut.sysname, ostype, sizeof(ut.sysname));
  396 
  397                 /* copy hostname (sans domain) to nodename */
  398                 for (i = 0; i < 8 && hostname[i] != '.'; i++)
  399                         ut.nodename[i] = hostname[i];
  400                 ut.nodename[i] = '\0';
  401 
  402                 strlcpy(ut.release, osrelease, sizeof(ut.release));
  403                 strlcpy(ut.version, version, sizeof(ut.version));
  404                 strlcpy(ut.machine, machine, sizeof(ut.machine));
  405 
  406                 error = copyout((caddr_t)&ut,
  407                     (caddr_t)SCARG(uap, uts), sizeof(ut));
  408                 break;
  409 
  410         /* gethostname */
  411         case 5:
  412                 /* SCARG(uap, dev) is length */
  413                 i = SCARG(uap, dev);
  414                 if (i < 0) {
  415                         error = EINVAL;
  416                         break;
  417                 }
  418                 if (i > hostnamelen + 1)
  419                         i = hostnamelen + 1;
  420                 error = copyout((caddr_t)hostname, (caddr_t)SCARG(uap, uts), i);
  421                 break;
  422 
  423         case 1: /* ?? */
  424         case 2: /* ustat */
  425         case 3: /* ?? */
  426         case 4: /* sethostname */
  427         default:
  428                 error = EINVAL;
  429                 break;
  430         }
  431         return (error);
  432 }
  433 
  434 int
  435 hpux_sys_sysconf(p, v, retval)
  436         struct proc *p;
  437         void *v;
  438         register_t *retval;
  439 {
  440         struct hpux_sys_sysconf_args *uap = v;
  441         switch (SCARG(uap, name)) {
  442 
  443         /* clock ticks per second */
  444         case HPUX_SYSCONF_CLKTICK:
  445                 *retval = hz;
  446                 break;
  447 
  448         /* open files */
  449         case HPUX_SYSCONF_OPENMAX:
  450                 *retval = NOFILE;
  451                 break;
  452 
  453         /* architecture */
  454         case HPUX_SYSCONF_CPUTYPE:
  455                 *retval = hpux_cpu_sysconf_arch();
  456                 break;
  457         default:
  458                 /* XXX */
  459                 uprintf("HP-UX sysconf(%d) not implemented\n",
  460                     SCARG(uap, name));
  461                 return (EINVAL);
  462         }
  463         return (0);
  464 }
  465 
  466 int
  467 hpux_sys_ulimit(p, v, retval)
  468         struct proc *p;
  469         void *v;
  470         register_t *retval;
  471 {
  472         struct hpux_sys_ulimit_args *uap = v;
  473         struct rlimit *limp;
  474         int error = 0;
  475 
  476         limp = &p->p_rlimit[RLIMIT_FSIZE];
  477         switch (SCARG(uap, cmd)) {
  478         case 2:
  479                 SCARG(uap, newlimit) *= 512;
  480                 if (SCARG(uap, newlimit) > limp->rlim_max &&
  481                     (error = suser(p, 0)))
  482                         break;
  483                 limp->rlim_cur = limp->rlim_max = SCARG(uap, newlimit);
  484                 /* else fall into... */
  485 
  486         case 1:
  487                 *retval = limp->rlim_max / 512;
  488                 break;
  489 
  490         case 3:
  491                 limp = &p->p_rlimit[RLIMIT_DATA];
  492                 *retval = ctob(p->p_vmspace->vm_tsize) + limp->rlim_max;
  493                 break;
  494 
  495         default:
  496                 error = EINVAL;
  497                 break;
  498         }
  499         return (error);
  500 }
  501 
  502 /*
  503  * Map "real time" priorities 0 (high) thru 127 (low) into nice
  504  * values -16 (high) thru -1 (low).
  505  */
  506 int
  507 hpux_sys_rtprio(cp, v, retval)
  508         struct proc *cp;
  509         void *v;
  510         register_t *retval;
  511 {
  512         struct hpux_sys_rtprio_args *uap = v;
  513         struct proc *p;
  514         int nice, error;
  515 
  516         if (SCARG(uap, prio) < RTPRIO_MIN && SCARG(uap, prio) > RTPRIO_MAX &&
  517             SCARG(uap, prio) != RTPRIO_NOCHG &&
  518             SCARG(uap, prio) != RTPRIO_RTOFF)
  519                 return (EINVAL);
  520         if (SCARG(uap, pid) == 0)
  521                 p = cp;
  522         else if ((p = pfind(SCARG(uap, pid))) == 0)
  523                 return (ESRCH);
  524         nice = p->p_nice;
  525         if (nice < NZERO)
  526                 *retval = (nice + 16) << 3;
  527         else
  528                 *retval = RTPRIO_RTOFF;
  529         switch (SCARG(uap, prio)) {
  530 
  531         case RTPRIO_NOCHG:
  532                 return (0);
  533 
  534         case RTPRIO_RTOFF:
  535                 if (nice >= NZERO)
  536                         return (0);
  537                 nice = NZERO;
  538                 break;
  539 
  540         default:
  541                 nice = (SCARG(uap, prio) >> 3) - 16;
  542                 break;
  543         }
  544         error = donice(cp, p, nice);
  545         if (error == EACCES)
  546                 error = EPERM;
  547         return (error);
  548 }
  549 
  550 /* hpux_sys_advise() is found in hpux_machdep.c */
  551 
  552 #ifdef PTRACE
  553 
  554 int
  555 hpux_sys_ptrace(p, v, retval)
  556         struct proc *p;
  557         void *v;
  558         register_t *retval;
  559 {
  560         struct hpux_sys_ptrace_args *uap = v;
  561         int error;
  562 #if defined(PT_READ_U) || defined(PT_WRITE_U)
  563         int isps = 0;
  564         struct proc *cp;
  565 #endif
  566 
  567         switch (SCARG(uap, req)) {
  568         /* map signal */
  569 #if defined(PT_STEP) || defined(PT_CONTINUE)
  570 # ifdef PT_STEP
  571         case PT_STEP:
  572 # endif
  573 # ifdef PT_CONTINUE
  574         case PT_CONTINUE:
  575 # endif
  576                 if (SCARG(uap, data)) {
  577                         SCARG(uap, data) = hpuxtobsdsig(SCARG(uap, data));
  578                         if (SCARG(uap, data) == 0)
  579                                 SCARG(uap, data) = NSIG;
  580                 }
  581                 break;
  582 #endif
  583         /* map u-area offset */
  584 #if defined(PT_READ_U) || defined(PT_WRITE_U)
  585 # ifdef PT_READ_U
  586         case PT_READ_U:
  587 # endif
  588 # ifdef PT_WRITE_U
  589         case PT_WRITE_U:
  590 # endif
  591                 /*
  592                  * Big, cheezy hack: hpux_to_bsd_uoff is really intended
  593                  * to be called in the child context (procxmt) but we
  594                  * do it here in the parent context to avoid hacks in
  595                  * the MI sys_process.c file.  This works only because
  596                  * we can access the child's md_regs pointer and it
  597                  * has the correct value (the child has already trapped
  598                  * into the kernel).
  599                  */
  600                 if ((cp = pfind(SCARG(uap, pid))) == 0)
  601                         return (ESRCH);
  602                 SCARG(uap, addr) =
  603                     (int *)hpux_to_bsd_uoff(SCARG(uap, addr), &isps, cp);
  604 
  605                 /*
  606                  * Since HP-UX PS is only 16-bits in ar0, requests
  607                  * to write PS actually contain the PS in the high word
  608                  * and the high half of the PC (the following register)
  609                  * in the low word.  Move the PS value to where BSD
  610                  * expects it.
  611                  */
  612                 if (isps && SCARG(uap, req) == PT_WRITE_U)
  613                         SCARG(uap, data) >>= 16;
  614                 break;
  615 #endif
  616         }
  617 
  618         error = sys_ptrace(p, uap, retval);
  619         /*
  620          * Align PS as HP-UX expects it (see WRITE_U comment above).
  621          * Note that we do not return the high part of PC like HP-UX
  622          * would, but the HP-UX debuggers don't require it.
  623          */
  624 #ifdef PT_READ_U
  625         if (isps && error == 0 && SCARG(uap, req) == PT_READ_U)
  626                 *retval <<= 16;
  627 #endif
  628         return (error);
  629 }
  630 
  631 #endif  /* PTRACE */
  632 
  633 #ifdef SYSVSHM
  634 #include <sys/shm.h>
  635 
  636 int
  637 hpux_sys_shmctl(p, v, retval)
  638         struct proc *p;
  639         void *v;
  640         register_t *retval;
  641 {
  642         struct hpux_sys_shmctl_args *uap = v;
  643 
  644         return (hpux_shmctl1(p, (struct hpux_sys_shmctl_args *)uap, retval, 0));
  645 }
  646 
  647 int
  648 hpux_sys_nshmctl(p, v, retval)
  649         struct proc *p;
  650         void *v;
  651         register_t *retval;     /* struct hpux_nshmctl_args * */
  652 {
  653         struct hpux_sys_nshmctl_args *uap = v;
  654 
  655         return (hpux_shmctl1(p, (struct hpux_sys_shmctl_args *)uap, retval, 1));
  656 }
  657 
  658 /*
  659  * Handle HP-UX specific commands.
  660  */
  661 int
  662 hpux_shmctl1(p, uap, retval, isnew)
  663         struct proc *p;
  664         struct hpux_sys_shmctl_args *uap;
  665         register_t *retval;
  666         int isnew;
  667 {
  668         struct shmid_ds *shp;
  669         struct ucred *cred = p->p_ucred;
  670         struct hpux_shmid_ds sbuf;
  671         int error;
  672         extern struct shmid_ds *shm_find_segment_by_shmid(int);
  673 
  674         if ((shp = shm_find_segment_by_shmid(SCARG(uap, shmid))) == NULL)
  675                 return EINVAL;
  676 
  677         switch (SCARG(uap, cmd)) {
  678         case SHM_LOCK:
  679         case SHM_UNLOCK:
  680                 /* don't really do anything, but make them think we did */
  681                 if (cred->cr_uid && cred->cr_uid != shp->shm_perm.uid &&
  682                     cred->cr_uid != shp->shm_perm.cuid)
  683                         return (EPERM);
  684                 return (0);
  685 
  686         case IPC_STAT:
  687                 if (!isnew)
  688                         break;
  689                 error = ipcperm(cred, &shp->shm_perm, IPC_R);
  690                 if (error == 0) {
  691                         sbuf.shm_perm.uid = shp->shm_perm.uid;
  692                         sbuf.shm_perm.gid = shp->shm_perm.gid;
  693                         sbuf.shm_perm.cuid = shp->shm_perm.cuid;
  694                         sbuf.shm_perm.cgid = shp->shm_perm.cgid;
  695                         sbuf.shm_perm.mode = shp->shm_perm.mode;
  696                         sbuf.shm_perm.seq = shp->shm_perm.seq;
  697                         sbuf.shm_perm.key = shp->shm_perm.key;
  698                         sbuf.shm_segsz = shp->shm_segsz;
  699                         sbuf.shm_ptbl = shp->shm_internal;      /* XXX */
  700                         sbuf.shm_lpid = shp->shm_lpid;
  701                         sbuf.shm_cpid = shp->shm_cpid;
  702                         sbuf.shm_nattch = shp->shm_nattch;
  703                         sbuf.shm_cnattch = shp->shm_nattch;     /* XXX */
  704                         sbuf.shm_atime = shp->shm_atime;
  705                         sbuf.shm_dtime = shp->shm_dtime;
  706                         sbuf.shm_ctime = shp->shm_ctime;
  707                         error = copyout((caddr_t)&sbuf, SCARG(uap, buf),
  708                             sizeof sbuf);
  709                 }
  710                 return (error);
  711 
  712         case IPC_SET:
  713                 if (!isnew)
  714                         break;
  715                 if (cred->cr_uid && cred->cr_uid != shp->shm_perm.uid &&
  716                     cred->cr_uid != shp->shm_perm.cuid) {
  717                         return (EPERM);
  718                 }
  719                 error = copyin(SCARG(uap, buf), (caddr_t)&sbuf, sizeof sbuf);
  720                 if (error == 0) {
  721                         shp->shm_perm.uid = sbuf.shm_perm.uid;
  722                         shp->shm_perm.gid = sbuf.shm_perm.gid;
  723                         shp->shm_perm.mode = (shp->shm_perm.mode & ~0777)
  724                                 | (sbuf.shm_perm.mode & 0777);
  725                         shp->shm_ctime = time_second;
  726                 }
  727                 return (error);
  728         }
  729         return (sys_shmctl(p, uap, retval));
  730 }
  731 #endif
  732 
  733 /*
  734  * HP-UX mmap() emulation (mainly for shared library support).
  735  */
  736 int
  737 hpux_sys_mmap(p, v, retval)
  738         struct proc *p;
  739         void *v;
  740         register_t *retval;
  741 {
  742         struct hpux_sys_mmap_args *uap = v;
  743         struct sys_mmap_args /* {
  744                 syscallarg(caddr_t) addr;
  745                 syscallarg(size_t) len;
  746                 syscallarg(int) prot;
  747                 syscallarg(int) flags;
  748                 syscallarg(int) fd;
  749                 syscallarg(long) pad;
  750                 syscallarg(off_t) pos;
  751         } */ nargs;
  752 
  753         SCARG(&nargs, addr) = SCARG(uap, addr);
  754         SCARG(&nargs, len) = SCARG(uap, len);
  755         SCARG(&nargs, prot) = SCARG(uap, prot);
  756         SCARG(&nargs, flags) = SCARG(uap, flags) &
  757                 ~(HPUXMAP_FIXED|HPUXMAP_REPLACE|HPUXMAP_ANON);
  758         if (SCARG(uap, flags) & HPUXMAP_FIXED)
  759                 SCARG(&nargs, flags) |= MAP_FIXED;
  760         if (SCARG(uap, flags) & HPUXMAP_ANON)
  761                 SCARG(&nargs, flags) |= MAP_ANON;
  762         SCARG(&nargs, fd) = (SCARG(&nargs, flags) & MAP_ANON) ? -1 : SCARG(uap, fd);
  763         SCARG(&nargs, pos) = SCARG(uap, pos);
  764 
  765         return (sys_mmap(p, &nargs, retval));
  766 }
  767 
  768 int
  769 hpuxtobsdioctl(com)
  770         u_long com;
  771 {
  772         switch (com) {
  773         case HPUXTIOCSLTC:
  774                 com = TIOCSLTC; break;
  775         case HPUXTIOCGLTC:
  776                 com = TIOCGLTC; break;
  777         case HPUXTIOCSPGRP:
  778                 com = TIOCSPGRP; break;
  779         case HPUXTIOCGPGRP:
  780                 com = TIOCGPGRP; break;
  781         case HPUXTIOCLBIS:
  782                 com = TIOCLBIS; break;
  783         case HPUXTIOCLBIC:
  784                 com = TIOCLBIC; break;
  785         case HPUXTIOCLSET:
  786                 com = TIOCLSET; break;
  787         case HPUXTIOCLGET:
  788                 com = TIOCLGET; break;
  789         case HPUXTIOCGWINSZ:
  790                 com = TIOCGWINSZ; break;
  791         case HPUXTIOCSWINSZ:
  792                 com = TIOCSWINSZ; break;
  793         }
  794         return(com);
  795 }
  796 
  797 /*
  798  * HP-UX ioctl system call.  The differences here are:
  799  *      IOC_IN also means IOC_VOID if the size portion is zero.
  800  *      no FIOCLEX/FIONCLEX/FIOASYNC/FIOGETOWN/FIOSETOWN
  801  *      the sgttyb struct is 2 bytes longer
  802  */
  803 int
  804 hpux_sys_ioctl(p, v, retval)
  805         struct proc *p;
  806         void *v;
  807         register_t *retval;
  808 {
  809         struct hpux_sys_ioctl_args /* {
  810                 syscallarg(int) fd;
  811                 syscallarg(int) com;
  812                 syscallarg(caddr_t) data;
  813         } */ *uap = v;
  814         struct filedesc *fdp = p->p_fd;
  815         struct file *fp;
  816         int com, error = 0;
  817         u_int size;
  818         caddr_t memp = 0;
  819 #define STK_PARAMS      128
  820         char stkbuf[STK_PARAMS];
  821         caddr_t dt = stkbuf;
  822 
  823         com = SCARG(uap, com);
  824 
  825         /* XXX */
  826         if (com == HPUXTIOCGETP || com == HPUXTIOCSETP)
  827                 return (getsettty(p, SCARG(uap, fd), com, SCARG(uap, data)));
  828 
  829         if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
  830                 return (EBADF);
  831         if ((fp->f_flag & (FREAD|FWRITE)) == 0)
  832                 return (EBADF);
  833 
  834         /*
  835          * Interpret high order word to find
  836          * amount of data to be copied to/from the
  837          * user's address space.
  838          */
  839         size = IOCPARM_LEN(com);
  840         if (size > IOCPARM_MAX)
  841                 return (ENOTTY);
  842         FREF(fp);
  843         if (size > sizeof (stkbuf)) {
  844                 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
  845                 dt = memp;
  846         }
  847         if (com&IOC_IN) {
  848                 if (size) {
  849                         error = copyin(SCARG(uap, data), dt, (u_int)size);
  850                         if (error) {
  851                                 goto out;
  852                         }
  853                 } else
  854                         *(caddr_t *)dt = SCARG(uap, data);
  855         } else if ((com&IOC_OUT) && size)
  856                 /*
  857                  * Zero the buffer so the user always
  858                  * gets back something deterministic.
  859                  */
  860                 bzero(dt, size);
  861         else if (com&IOC_VOID)
  862                 *(caddr_t *)dt = SCARG(uap, data);
  863 
  864         switch (com) {
  865 
  866         case HPUXFIOSNBIO:
  867         {
  868                 char *ofp = &fdp->fd_ofileflags[SCARG(uap, fd)];
  869                 int tmp;
  870 
  871                 if (*(int *)dt)
  872                         *ofp |= HPUX_UF_FIONBIO_ON;
  873                 else
  874                         *ofp &= ~HPUX_UF_FIONBIO_ON;
  875                 /*
  876                  * Only set/clear if O_NONBLOCK/FNDELAY not in effect
  877                  */
  878                 if ((*ofp & (HPUX_UF_NONBLOCK_ON|HPUX_UF_FNDELAY_ON)) == 0) {
  879                         tmp = *ofp & HPUX_UF_FIONBIO_ON;
  880                         error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO,
  881                                                        (caddr_t)&tmp, p);
  882                 }
  883                 break;
  884         }
  885 
  886         case HPUXTIOCCONS:
  887                 *(int *)dt = 1;
  888                 error = (*fp->f_ops->fo_ioctl)(fp, TIOCCONS, dt, p);
  889                 break;
  890 
  891         /* BSD-style job control ioctls */
  892         case HPUXTIOCLBIS:
  893         case HPUXTIOCLBIC:
  894         case HPUXTIOCLSET:
  895                 *(int *)dt &= HPUXLTOSTOP;
  896                 if (*(int *)dt & HPUXLTOSTOP)
  897                         *(int *)dt = LTOSTOP;
  898                 /* fall into */
  899 
  900         /* simple mapping cases */
  901         case HPUXTIOCLGET:
  902         case HPUXTIOCSLTC:
  903         case HPUXTIOCGLTC:
  904         case HPUXTIOCSPGRP:
  905         case HPUXTIOCGPGRP:
  906         case HPUXTIOCGWINSZ:
  907         case HPUXTIOCSWINSZ:
  908                 error = (*fp->f_ops->fo_ioctl)
  909                         (fp, hpuxtobsdioctl(com), dt, p);
  910                 if (error == 0 && com == HPUXTIOCLGET) {
  911                         *(int *)dt &= LTOSTOP;
  912                         if (*(int *)dt & LTOSTOP)
  913                                 *(int *)dt = HPUXLTOSTOP;
  914                 }
  915                 break;
  916 
  917         /* SYS 5 termio and POSIX termios */
  918         case HPUXTCGETA:
  919         case HPUXTCSETA:
  920         case HPUXTCSETAW:
  921         case HPUXTCSETAF:
  922         case HPUXTCGETATTR:
  923         case HPUXTCSETATTR:
  924         case HPUXTCSETATTRD:
  925         case HPUXTCSETATTRF:
  926                 error = hpux_termio(SCARG(uap, fd), com, dt, p);
  927                 break;
  928 
  929         default:
  930                 error = (*fp->f_ops->fo_ioctl)(fp, com, dt, p);
  931                 break;
  932         }
  933         /*
  934          * Copy any data to user, size was
  935          * already set and checked above.
  936          */
  937         if (error == 0 && (com&IOC_OUT) && size)
  938                 error = copyout(dt, SCARG(uap, data), (u_int)size);
  939 
  940 out:
  941         FRELE(fp);
  942         if (memp)
  943                 free(memp, M_IOCTLOPS);
  944         return (error);
  945 }
  946 
  947 /* hpux_sys_getcontext() is found in hpux_machdep.c */
  948 
  949 /*
  950  * This is the equivalent of BSD getpgrp but with more restrictions.
  951  * Note we do not check the real uid or "saved" uid.
  952  */
  953 int
  954 hpux_sys_getpgrp2(cp, v, retval)
  955         struct proc *cp;
  956         void *v;
  957         register_t *retval;
  958 {
  959         struct hpux_sys_getpgrp2_args *uap = v;
  960         struct proc *p;
  961 
  962         if (SCARG(uap, pid) == 0)
  963                 SCARG(uap, pid) = cp->p_pid;
  964         p = pfind(SCARG(uap, pid));
  965         if (p == 0)
  966                 return (ESRCH);
  967         if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
  968             !inferior(p))
  969                 return (EPERM);
  970         *retval = p->p_pgid;
  971         return (0);
  972 }
  973 
  974 /*
  975  * This is the equivalent of BSD setpgrp but with more restrictions.
  976  * Note we do not check the real uid or "saved" uid or pgrp.
  977  */
  978 int
  979 hpux_sys_setpgrp2(p, v, retval)
  980         struct proc *p;
  981         void *v;
  982         register_t *retval;
  983 {
  984         struct hpux_sys_setpgrp2_args *uap = v;
  985 
  986         /* empirically determined */
  987         if (SCARG(uap, pgid) < 0 || SCARG(uap, pgid) >= 30000)
  988                 return (EINVAL);
  989         return (sys_setpgid(p, uap, retval));
  990 }
  991 
  992 int
  993 hpux_sys_getrlimit(p, v, retval)
  994         struct proc *p;
  995         void *v;
  996         register_t *retval;
  997 {
  998         struct hpux_sys_getrlimit_args *uap = v;
  999         struct compat_43_sys_getrlimit_args ap;
 1000 
 1001         if (SCARG(uap, which) > HPUXRLIMIT_NOFILE)
 1002                 return (EINVAL);
 1003         if (SCARG(uap, which) == HPUXRLIMIT_NOFILE)
 1004                 SCARG(uap, which) = RLIMIT_NOFILE;
 1005 
 1006         SCARG(&ap, which) = SCARG(uap, which);
 1007         SCARG(&ap, rlp) = SCARG(uap, rlp);
 1008 
 1009         return (compat_43_sys_getrlimit(p, uap, retval));
 1010 }
 1011 
 1012 int
 1013 hpux_sys_setrlimit(p, v, retval)
 1014         struct proc *p;
 1015         void *v;
 1016         register_t *retval;
 1017 {
 1018         struct hpux_sys_setrlimit_args *uap = v;
 1019         struct compat_43_sys_setrlimit_args ap;
 1020 
 1021         if (SCARG(uap, which) > HPUXRLIMIT_NOFILE)
 1022                 return (EINVAL);
 1023         if (SCARG(uap, which) == HPUXRLIMIT_NOFILE)
 1024                 SCARG(uap, which) = RLIMIT_NOFILE;
 1025 
 1026         SCARG(&ap, which) = SCARG(uap, which);
 1027         SCARG(&ap, rlp) = SCARG(uap, rlp);
 1028 
 1029         return (compat_43_sys_setrlimit(p, uap, retval));
 1030 }
 1031 
 1032 /*
 1033  * XXX: simple recognition hack to see if we can make grmd work.
 1034  */
 1035 int
 1036 hpux_sys_lockf(p, v, retval)
 1037         struct proc *p;
 1038         void *v;
 1039         register_t *retval;
 1040 {
 1041         /* struct hpux_sys_lockf_args *uap = v; */
 1042 
 1043         return (0);
 1044 }
 1045 
 1046 
 1047 #ifndef __hppa__
 1048 int
 1049 hpux_sys_getaccess(p, v, retval)
 1050         struct proc *p;
 1051         void *v;
 1052         register_t *retval;
 1053 {
 1054         struct hpux_sys_getaccess_args *uap = v;
 1055         int lgroups[NGROUPS];
 1056         int error = 0;
 1057         struct ucred *cred;
 1058         struct vnode *vp;
 1059         struct nameidata nd;
 1060 
 1061         /*
 1062          * Build an appropriate credential structure
 1063          */
 1064         cred = crdup(p->p_ucred);
 1065         switch (SCARG(uap, uid)) {
 1066         case 65502:     /* UID_EUID */
 1067                 break;
 1068         case 65503:     /* UID_RUID */
 1069                 cred->cr_uid = p->p_cred->p_ruid;
 1070                 break;
 1071         case 65504:     /* UID_SUID */
 1072                 error = EINVAL;
 1073                 break;
 1074         default:
 1075                 if (SCARG(uap, uid) > 65504)
 1076                         error = EINVAL;
 1077                 cred->cr_uid = SCARG(uap, uid);
 1078                 break;
 1079         }
 1080         switch (SCARG(uap, ngroups)) {
 1081         case -1:        /* NGROUPS_EGID */
 1082                 cred->cr_ngroups = 1;
 1083                 break;
 1084         case -5:        /* NGROUPS_EGID_SUPP */
 1085                 break;
 1086         case -2:        /* NGROUPS_RGID */
 1087                 cred->cr_ngroups = 1;
 1088                 cred->cr_gid = p->p_cred->p_rgid;
 1089                 break;
 1090         case -6:        /* NGROUPS_RGID_SUPP */
 1091                 cred->cr_gid = p->p_cred->p_rgid;
 1092                 break;
 1093         case -3:        /* NGROUPS_SGID */
 1094         case -7:        /* NGROUPS_SGID_SUPP */
 1095                 error = EINVAL;
 1096                 break;
 1097         case -4:        /* NGROUPS_SUPP */
 1098                 if (cred->cr_ngroups > 1)
 1099                         cred->cr_gid = cred->cr_groups[1];
 1100                 else
 1101                         error = EINVAL;
 1102                 break;
 1103         default:
 1104                 if (SCARG(uap, ngroups) > 0 && SCARG(uap, ngroups) <= NGROUPS)
 1105                         error = copyin((caddr_t)SCARG(uap, gidset),
 1106                                        (caddr_t)&lgroups[0],
 1107                                        SCARG(uap, ngroups) *
 1108                                            sizeof(lgroups[0]));
 1109                 else
 1110                         error = EINVAL;
 1111                 if (error == 0) {
 1112                         int gid;
 1113 
 1114                         for (gid = 0; gid < SCARG(uap, ngroups); gid++)
 1115                                 cred->cr_groups[gid] = lgroups[gid];
 1116                         cred->cr_ngroups = SCARG(uap, ngroups);
 1117                 }
 1118                 break;
 1119         }
 1120         /*
 1121          * Lookup file using caller's effective IDs.
 1122          */
 1123         if (error == 0) {
 1124                 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
 1125                         SCARG(uap, path), p);
 1126                 error = namei(&nd);
 1127         }
 1128         if (error) {
 1129                 crfree(cred);
 1130                 return (error);
 1131         }
 1132         /*
 1133          * Use the constructed credentials for access checks.
 1134          */
 1135         vp = nd.ni_vp;
 1136         *retval = 0;
 1137         if (VOP_ACCESS(vp, VREAD, cred, p) == 0)
 1138                 *retval |= R_OK;
 1139         if (vn_writechk(vp) == 0 && VOP_ACCESS(vp, VWRITE, cred, p) == 0)
 1140                 *retval |= W_OK;
 1141         if (VOP_ACCESS(vp, VEXEC, cred, p) == 0)
 1142                 *retval |= X_OK;
 1143         vput(vp);
 1144         crfree(cred);
 1145         return (error);
 1146 }
 1147 #endif
 1148 
 1149 /*
 1150  * Ancient HP-UX system calls.  Some 9.x executables even use them!
 1151  */
 1152 #define HPUX_HZ 50
 1153 
 1154 #include <sys/times.h>
 1155 
 1156 
 1157 /*
 1158  * SYS V style setpgrp()
 1159  */
 1160 int
 1161 hpux_sys_setpgrp_6x(p, v, retval)
 1162         struct proc *p;
 1163         void *v;
 1164         register_t *retval;
 1165 {
 1166 
 1167         if (p->p_pid != p->p_pgid)
 1168                 enterpgrp(p, p->p_pid, 0);
 1169         *retval = p->p_pgid;
 1170         return (0);
 1171 }
 1172 
 1173 int
 1174 hpux_sys_time_6x(p, v, retval)
 1175         struct proc *p;
 1176         void *v;
 1177         register_t *retval;
 1178 {
 1179         struct hpux_sys_time_6x_args /* {
 1180                 syscallarg(time_t *) t;
 1181         } */ *uap = v;
 1182         int error = 0;
 1183         struct timeval tv;
 1184 
 1185         microtime(&tv);
 1186         if (SCARG(uap, t) != NULL)
 1187                 error = copyout(&tv.tv_sec, SCARG(uap, t), sizeof(time_t));
 1188 
 1189         *retval = (register_t)tv.tv_sec;
 1190         return (error);
 1191 }
 1192 
 1193 int
 1194 hpux_sys_stime_6x(p, v, retval)
 1195         struct proc *p;
 1196         void *v;
 1197         register_t *retval;
 1198 {
 1199         struct hpux_sys_stime_6x_args /* {
 1200                 syscallarg(int) time;
 1201         } */ *uap = v;
 1202         struct timespec ts;
 1203         int error;
 1204 
 1205         ts.tv_sec = SCARG(uap, time);
 1206         ts.tv_nsec = 0;
 1207         if ((error = suser(p, 0)))
 1208                 return (error);
 1209 
 1210         settime(&ts);
 1211 
 1212         return (0);
 1213 }
 1214 
 1215 int
 1216 hpux_sys_ftime_6x(p, v, retval)
 1217         struct proc *p;
 1218         void *v;
 1219         register_t *retval;
 1220 {
 1221         struct hpux_sys_ftime_6x_args /* {
 1222                 syscallarg(struct hpux_timeb *) tp;
 1223         } */ *uap = v;
 1224         struct hpux_otimeb tb;
 1225         struct timeval tv;
 1226 
 1227         microtime(&tv);
 1228         tb.time = tv.tv_sec;
 1229         tb.millitm = tv.tv_usec / 1000;
 1230         tb.timezone = tz.tz_minuteswest;
 1231         tb.dstflag = tz.tz_dsttime;
 1232         return (copyout((caddr_t)&tb, (caddr_t)SCARG(uap, tp), sizeof (tb)));
 1233 }
 1234 
 1235 int
 1236 hpux_sys_alarm_6x(p, v, retval)
 1237         struct proc *p;
 1238         void *v;
 1239         register_t *retval;
 1240 {
 1241         struct hpux_sys_alarm_6x_args /* {
 1242                 syscallarg(int) deltat;
 1243         } */ *uap = v;
 1244         int timo;
 1245         struct timeval tv, atv;
 1246 
 1247         timeout_del(&p->p_realit_to);
 1248         timerclear(&p->p_realtimer.it_interval);
 1249         *retval = 0;
 1250         getmicrouptime(&tv);
 1251         if (timerisset(&p->p_realtimer.it_value) &&
 1252             timercmp(&p->p_realtimer.it_value, &tv, >))
 1253                 *retval = p->p_realtimer.it_value.tv_sec - tv.tv_sec;
 1254         if (SCARG(uap, deltat) == 0) {
 1255                 timerclear(&p->p_realtimer.it_value);
 1256                 return (0);
 1257         }
 1258         atv.tv_sec = SCARG(uap, deltat);
 1259         atv.tv_usec = 0;
 1260         p->p_realtimer.it_value = tv;
 1261         p->p_realtimer.it_value.tv_sec += SCARG(uap, deltat);
 1262         timo = tvtohz(&atv);
 1263         if (timo <= 0)
 1264                 timo = 1;
 1265         timeout_add(&p->p_realit_to, timo);
 1266         return (0);
 1267 }
 1268 
 1269 int
 1270 hpux_sys_nice_6x(p, v, retval)
 1271         struct proc *p;
 1272         void *v;
 1273         register_t *retval;
 1274 {
 1275         struct hpux_sys_nice_6x_args /* {
 1276                 syscallarg(int) nval;
 1277         } */ *uap = v;
 1278         int error;
 1279 
 1280         error = donice(p, p, (p->p_nice-NZERO)+SCARG(uap, nval));
 1281         if (error == 0)
 1282                 *retval = p->p_nice - NZERO;
 1283         return (error);
 1284 }
 1285 
 1286 int
 1287 hpux_sys_times_6x(p, v, retval)
 1288         struct proc *p;
 1289         void *v;
 1290         register_t *retval;
 1291 {
 1292         struct hpux_sys_times_6x_args /* {
 1293                 syscallarg(struct tms *) tms;
 1294         } */ *uap = v;
 1295         struct timeval ru, rs;
 1296         struct tms atms;
 1297         int error;
 1298 
 1299         calcru(p, &ru, &rs, NULL);
 1300         atms.tms_utime = hpux_scale(&ru);
 1301         atms.tms_stime = hpux_scale(&rs);
 1302         atms.tms_cutime = hpux_scale(&p->p_stats->p_cru.ru_utime);
 1303         atms.tms_cstime = hpux_scale(&p->p_stats->p_cru.ru_stime);
 1304         error = copyout((caddr_t)&atms, (caddr_t)SCARG(uap, tms),
 1305             sizeof (atms));
 1306         if (error == 0) {
 1307                 struct timeval tv;
 1308                 getmicrouptime(&tv);
 1309                 *(time_t *)retval = hpux_scale(&tv);
 1310         }
 1311         return (error);
 1312 }
 1313 
 1314 /*
 1315  * Doesn't exactly do what the documentation says.
 1316  * What we really do is return 1/HPUX_HZ-th of a second since that
 1317  * is what HP-UX returns.
 1318  */
 1319 static int
 1320 hpux_scale(tvp)
 1321         struct timeval *tvp;
 1322 {
 1323         return (tvp->tv_sec * HPUX_HZ + tvp->tv_usec * HPUX_HZ / 1000000);
 1324 }
 1325 
 1326 /*
 1327  * Set IUPD and IACC times on file.
 1328  * Can't set ICHG.
 1329  */
 1330 int
 1331 hpux_sys_utime_6x(p, v, retval)
 1332         struct proc *p;
 1333         void *v;
 1334         register_t *retval;
 1335 {
 1336         struct hpux_sys_utime_6x_args /* {
 1337                 syscallarg(char *) fname;
 1338                 syscallarg(time_t *) tptr;
 1339         } */ *uap = v;
 1340         struct vnode *vp;
 1341         struct vattr vattr;
 1342         time_t tv[2];
 1343         int error;
 1344         struct nameidata nd;
 1345 
 1346         if (SCARG(uap, tptr)) {
 1347                 error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv,
 1348                     sizeof (tv));
 1349                 if (error)
 1350                         return (error);
 1351         } else
 1352                 tv[0] = tv[1] = time_second;
 1353         vattr_null(&vattr);
 1354         vattr.va_atime.tv_sec = tv[0];
 1355         vattr.va_atime.tv_nsec = 0;
 1356         vattr.va_mtime.tv_sec = tv[1];
 1357         vattr.va_mtime.tv_nsec = 0;
 1358         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
 1359             SCARG(uap, fname), p);
 1360         if ((error = namei(&nd)))
 1361                 return (error);
 1362         vp = nd.ni_vp;
 1363         if (vp->v_mount->mnt_flag & MNT_RDONLY)
 1364                 error = EROFS;
 1365         else
 1366                 error = VOP_SETATTR(vp, &vattr, nd.ni_cnd.cn_cred, p);
 1367         vput(vp);
 1368         return (error);
 1369 }
 1370 
 1371 int
 1372 hpux_sys_pause_6x(p, v, retval)
 1373         struct proc *p;
 1374         void *v;
 1375         register_t *retval;
 1376 {
 1377         struct sys_sigsuspend_args bsa;
 1378 
 1379         SCARG(&bsa, mask) = p->p_sigmask;
 1380         return (sys_sigsuspend(p, &bsa, retval));
 1381 }

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