Annotation of sys/compat/hpux/hpux_compat.c, Revision 1.1
1.1 ! nbrk 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: }
CVSweb