1 /* $NetBSD: ultrix_misc.c,v 1.35 1997/06/09 11:57:48 jonathan Exp $ */ 2 3 /* 4 * Copyright (c) 1995, 1997 Jonathan Stone (hereinafter referred to as the author) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Matthew R. Green for 18 * the NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1992, 1993 37 * The Regents of the University of California. All rights reserved. 38 * 39 * This software was developed by the Computer Systems Engineering group 40 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 41 * contributed to Berkeley. 42 * 43 * All advertising materials mentioning features or use of this software 44 * must display the following acknowledgement: 45 * This product includes software developed by the University of 46 * California, Lawrence Berkeley Laboratory. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. All advertising materials mentioning features or use of this software 57 * must display the following acknowledgement: 58 * This product includes software developed by the University of 59 * California, Berkeley and its contributors. 60 * 4. Neither the name of the University nor the names of its contributors 61 * may be used to endorse or promote products derived from this software 62 * without specific prior written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 74 * SUCH DAMAGE. 75 * 76 * 77 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93 78 * 79 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp 80 */ 81 82 /* 83 * SunOS compatibility module. 84 * 85 * SunOS system calls that are implemented differently in BSD are 86 * handled here. 87 */ 88 89 #include <sys/param.h> 90 #include <sys/systm.h> 91 #include <sys/namei.h> 92 #include <sys/dirent.h> 93 #include <sys/proc.h> 94 #include <sys/file.h> 95 #include <sys/filedesc.h> 96 /*#include <sys/stat.h>*/ 97 /*#include <sys/ioctl.h>*/ 98 #include <sys/kernel.h> 99 #include <sys/exec.h> 100 #include <sys/malloc.h> 101 #include <sys/mbuf.h> 102 #include <sys/mman.h> 103 #include <sys/mount.h> 104 #include <sys/resource.h> 105 #include <sys/resourcevar.h> 106 #include <sys/signal.h> 107 #include <sys/signalvar.h> 108 #include <sys/socket.h> 109 #include <sys/vnode.h> 110 #include <sys/uio.h> 111 #include <sys/wait.h> 112 #include <sys/utsname.h> 113 #include <sys/unistd.h> 114 #include <sys/ipc.h> 115 116 #include <sys/syscallargs.h> 117 118 #include <compat/ultrix/ultrix_syscall.h> 119 #include <compat/ultrix/ultrix_syscallargs.h> 120 #include <compat/common/compat_util.h> 121 122 #include <netinet/in.h> 123 124 #include <miscfs/specfs/specdev.h> 125 126 #include <nfs/rpcv2.h> 127 #include <nfs/nfsproto.h> 128 #include <nfs/nfs.h> 129 130 #include <vm/vm.h> /* pmap declarations */ 131 132 #include <sys/conf.h> /* iszerodev() */ 133 #include <sys/socketvar.h> /* sosetopt() */ 134 135 136 extern struct sysent ultrix_sysent[]; 137 extern char *ultrix_syscallnames[]; 138 139 140 /* 141 * Select the appropriate setregs callback for the target architecture. 142 */ 143 #ifdef mips 144 #include <machine/ecoff_machdep.h> 145 #define ULTRIX_EXEC_SETREGS cpu_exec_ecoff_setregs 146 #endif /* mips */ 147 148 #ifdef vax 149 #define ULTRIX_EXEC_SETREGS setregs 150 #endif /* mips */ 151 152 153 extern void ULTRIX_EXEC_SETREGS __P((struct proc *, struct exec_package *, 154 u_long, register_t *)); 155 extern char sigcode[], esigcode[]; 156 157 struct emul emul_ultrix = { 158 "ultrix", 159 NULL, 160 sendsig, 161 ULTRIX_SYS_syscall, 162 ULTRIX_SYS_MAXSYSCALL, 163 ultrix_sysent, 164 ultrix_syscallnames, 165 0, 166 copyargs, 167 ULTRIX_EXEC_SETREGS, 168 sigcode, 169 esigcode, 170 }; 171 172 #define GSI_PROG_ENV 1 173 174 int 175 ultrix_sys_getsysinfo(p, v, retval) 176 struct proc *p; 177 void *v; 178 register_t *retval; 179 { 180 struct ultrix_sys_getsysinfo_args *uap = v; 181 static short progenv = 0; 182 183 switch (SCARG(uap, op)) { 184 /* operations implemented: */ 185 case GSI_PROG_ENV: 186 if (SCARG(uap, nbytes) < sizeof(short)) 187 return EINVAL; 188 *retval = 1; 189 return (copyout(&progenv, SCARG(uap, buffer), sizeof(short))); 190 default: 191 *retval = 0; /* info unavail */ 192 return 0; 193 } 194 } 195 196 int 197 ultrix_sys_setsysinfo(p, v, retval) 198 struct proc *p; 199 void *v; 200 register_t *retval; 201 { 202 203 #ifdef notyet 204 struct ultrix_sys_setsysinfo_args *uap = v; 205 #endif 206 207 *retval = 0; 208 return 0; 209 } 210 211 int 212 ultrix_sys_waitpid(p, v, retval) 213 struct proc *p; 214 void *v; 215 register_t *retval; 216 { 217 struct ultrix_sys_waitpid_args *uap = v; 218 struct sys_wait4_args ua; 219 220 SCARG(&ua, pid) = SCARG(uap, pid); 221 SCARG(&ua, status) = SCARG(uap, status); 222 SCARG(&ua, options) = SCARG(uap, options); 223 SCARG(&ua, rusage) = 0; 224 225 return (sys_wait4(p, &ua, retval)); 226 } 227 228 int 229 ultrix_sys_wait3(p, v, retval) 230 struct proc *p; 231 void *v; 232 register_t *retval; 233 { 234 struct ultrix_sys_wait3_args *uap = v; 235 struct sys_wait4_args ua; 236 237 SCARG(&ua, pid) = -1; 238 SCARG(&ua, status) = SCARG(uap, status); 239 SCARG(&ua, options) = SCARG(uap, options); 240 SCARG(&ua, rusage) = SCARG(uap, rusage); 241 242 return (sys_wait4(p, &ua, retval)); 243 } 244 245 /* 246 * Ultrix binaries pass in FD_MAX as the first arg to select(). 247 * On Ultrix, FD_MAX is 4096, which is more than the NetBSD sys_select() 248 * can handle. 249 * Since we can't have more than the (native) FD_MAX descriptors open, 250 * limit nfds to at most FD_MAX. 251 */ 252 int 253 ultrix_sys_select(p, v, retval) 254 struct proc *p; 255 void *v; 256 register_t *retval; 257 { 258 struct sys_select_args *uap = v; 259 struct timeval atv; 260 int error; 261 262 /* Limit number of FDs selected on to the native maximum */ 263 264 if (SCARG(uap, nd) > FD_SETSIZE) 265 SCARG(uap, nd) = FD_SETSIZE; 266 267 /* Check for negative timeval */ 268 if (SCARG(uap, tv)) { 269 error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv, 270 sizeof(atv)); 271 if (error) 272 goto done; 273 #ifdef DEBUG 274 /* Ultrix clients sometimes give negative timeouts? */ 275 if (atv.tv_sec < 0 || atv.tv_usec < 0) 276 printf("ultrix select( %ld, %ld): negative timeout\n", 277 atv.tv_sec, atv.tv_usec); 278 /*tvp = (timeval *)STACKGAPBASE;*/ 279 #endif 280 281 } 282 error = sys_select(p, (void*) uap, retval); 283 if (error == EINVAL) 284 printf("ultrix select: bad args?\n"); 285 286 done: 287 return error; 288 } 289 290 #if defined(NFS) 291 int 292 async_daemon(p, v, retval) 293 struct proc *p; 294 void *v; 295 register_t *retval; 296 { 297 struct sys_nfssvc_args ouap; 298 299 SCARG(&ouap, flag) = NFSSVC_BIOD; 300 SCARG(&ouap, argp) = NULL; 301 302 return (sys_nfssvc(p, &ouap, retval)); 303 } 304 #endif /* NFS */ 305 306 307 #define SUN__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */ 308 309 int 310 ultrix_sys_mmap(p, v, retval) 311 register struct proc *p; 312 void *v; 313 register_t *retval; 314 { 315 register struct ultrix_sys_mmap_args *uap = v; 316 struct sys_mmap_args ouap; 317 register struct filedesc *fdp; 318 register struct file *fp; 319 register struct vnode *vp; 320 321 /* 322 * Verify the arguments. 323 */ 324 if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC)) 325 return (EINVAL); /* XXX still needed? */ 326 327 if ((SCARG(uap, flags) & SUN__MAP_NEW) == 0) 328 return (EINVAL); 329 330 SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUN__MAP_NEW; 331 SCARG(&ouap, addr) = SCARG(uap, addr); 332 333 if ((SCARG(&ouap, flags) & MAP_FIXED) == 0 && 334 SCARG(&ouap, addr) != 0 && 335 SCARG(&ouap, addr) < (caddr_t)round_page(p->p_vmspace->vm_daddr+MAXDSIZ)) 336 SCARG(&ouap, addr) = (caddr_t)round_page(p->p_vmspace->vm_daddr+MAXDSIZ); 337 338 SCARG(&ouap, len) = SCARG(uap, len); 339 SCARG(&ouap, prot) = SCARG(uap, prot); 340 SCARG(&ouap, fd) = SCARG(uap, fd); 341 SCARG(&ouap, pos) = SCARG(uap, pos); 342 343 /* 344 * Special case: if fd refers to /dev/zero, map as MAP_ANON. (XXX) 345 */ 346 fdp = p->p_fd; 347 if ((unsigned)SCARG(&ouap, fd) < fdp->fd_nfiles && /*XXX*/ 348 (fp = fdp->fd_ofiles[SCARG(&ouap, fd)]) != NULL && /*XXX*/ 349 fp->f_type == DTYPE_VNODE && /*XXX*/ 350 (vp = (struct vnode *)fp->f_data)->v_type == VCHR && /*XXX*/ 351 iszerodev(vp->v_rdev)) { /*XXX*/ 352 SCARG(&ouap, flags) |= MAP_ANON; 353 SCARG(&ouap, fd) = -1; 354 } 355 356 return (sys_mmap(p, &ouap, retval)); 357 } 358 359 int 360 ultrix_sys_setsockopt(p, v, retval) 361 struct proc *p; 362 void *v; 363 register_t *retval; 364 { 365 register struct ultrix_sys_setsockopt_args *uap = v; 366 struct file *fp; 367 struct mbuf *m = NULL; 368 int error; 369 370 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) 371 return (error); 372 #define SO_DONTLINGER (~SO_LINGER) 373 if (SCARG(uap, name) == SO_DONTLINGER) { 374 m = m_get(M_WAIT, MT_SOOPTS); 375 mtod(m, struct linger *)->l_onoff = 0; 376 m->m_len = sizeof(struct linger); 377 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level), 378 SO_LINGER, m)); 379 } 380 if (SCARG(uap, level) == IPPROTO_IP) { 381 #define EMUL_IP_MULTICAST_IF 2 382 #define EMUL_IP_MULTICAST_TTL 3 383 #define EMUL_IP_MULTICAST_LOOP 4 384 #define EMUL_IP_ADD_MEMBERSHIP 5 385 #define EMUL_IP_DROP_MEMBERSHIP 6 386 static int ipoptxlat[] = { 387 IP_MULTICAST_IF, 388 IP_MULTICAST_TTL, 389 IP_MULTICAST_LOOP, 390 IP_ADD_MEMBERSHIP, 391 IP_DROP_MEMBERSHIP 392 }; 393 if (SCARG(uap, name) >= EMUL_IP_MULTICAST_IF && 394 SCARG(uap, name) <= EMUL_IP_DROP_MEMBERSHIP) { 395 SCARG(uap, name) = 396 ipoptxlat[SCARG(uap, name) - EMUL_IP_MULTICAST_IF]; 397 } 398 } 399 if (SCARG(uap, valsize) > MLEN) 400 return (EINVAL); 401 if (SCARG(uap, val)) { 402 m = m_get(M_WAIT, MT_SOOPTS); 403 error = copyin(SCARG(uap, val), mtod(m, caddr_t), 404 (u_int)SCARG(uap, valsize)); 405 if (error) { 406 (void) m_free(m); 407 return (error); 408 } 409 m->m_len = SCARG(uap, valsize); 410 } 411 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level), 412 SCARG(uap, name), m)); 413 } 414 415 struct ultrix_utsname { 416 char sysname[9]; 417 char nodename[9]; 418 char nodeext[65-9]; 419 char release[9]; 420 char version[9]; 421 char machine[9]; 422 }; 423 424 int 425 ultrix_sys_uname(p, v, retval) 426 struct proc *p; 427 void *v; 428 register_t *retval; 429 { 430 struct ultrix_sys_uname_args *uap = v; 431 struct ultrix_utsname sut; 432 extern char ostype[], machine[], osrelease[]; 433 434 bzero(&sut, sizeof(sut)); 435 436 bcopy(ostype, sut.sysname, sizeof(sut.sysname) - 1); 437 bcopy(hostname, sut.nodename, sizeof(sut.nodename)); 438 sut.nodename[sizeof(sut.nodename)-1] = '\0'; 439 bcopy(osrelease, sut.release, sizeof(sut.release) - 1); 440 bcopy("1", sut.version, sizeof(sut.version) - 1); 441 bcopy(machine, sut.machine, sizeof(sut.machine) - 1); 442 443 return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, name), 444 sizeof(struct ultrix_utsname)); 445 } 446 447 int 448 ultrix_sys_setpgrp(p, v, retval) 449 struct proc *p; 450 void *v; 451 register_t *retval; 452 { 453 struct ultrix_sys_setpgrp_args *uap = v; 454 455 /* 456 * difference to our setpgid call is to include backwards 457 * compatibility to pre-setsid() binaries. Do setsid() 458 * instead of setpgid() in those cases where the process 459 * tries to create a new session the old way. 460 */ 461 if (!SCARG(uap, pgid) && 462 (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid)) 463 return sys_setsid(p, uap, retval); 464 else 465 return sys_setpgid(p, uap, retval); 466 } 467 468 #if defined (NFSSERVER) 469 int 470 ultrix_sys_nfssvc(p, v, retval) 471 struct proc *p; 472 void *v; 473 register_t *retval; 474 { 475 476 #if 0 /* XXX */ 477 struct ultrix_sys_nfssvc_args *uap = v; 478 struct emul *e = p->p_emul; 479 struct sys_nfssvc_args outuap; 480 struct sockaddr sa; 481 int error; 482 483 bzero(&outuap, sizeof outuap); 484 SCARG(&outuap, fd) = SCARG(uap, fd); 485 SCARG(&outuap, mskval) = STACKGAPBASE; 486 SCARG(&outuap, msklen) = sizeof sa; 487 SCARG(&outuap, mtchval) = outuap.mskval + sizeof sa; 488 SCARG(&outuap, mtchlen) = sizeof sa; 489 490 bzero(&sa, sizeof sa); 491 if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen))) 492 return (error); 493 if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen))) 494 return (error); 495 496 return nfssvc(p, &outuap, retval); 497 #else 498 return (ENOSYS); 499 #endif 500 } 501 #endif /* NFSSERVER */ 502 503 struct ultrix_ustat { 504 daddr_t f_tfree; /* total free */ 505 ino_t f_tinode; /* total inodes free */ 506 char f_fname[6]; /* filsys name */ 507 char f_fpack[6]; /* filsys pack name */ 508 }; 509 510 int 511 ultrix_sys_ustat(p, v, retval) 512 struct proc *p; 513 void *v; 514 register_t *retval; 515 { 516 struct ultrix_sys_ustat_args *uap = v; 517 struct ultrix_ustat us; 518 int error; 519 520 bzero(&us, sizeof us); 521 522 /* 523 * XXX: should set f_tfree and f_tinode at least 524 * How do we translate dev -> fstat? (and then to ultrix_ustat) 525 */ 526 527 if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0) 528 return (error); 529 return 0; 530 } 531 532 int 533 ultrix_sys_quotactl(p, v, retval) 534 struct proc *p; 535 void *v; 536 register_t *retval; 537 { 538 539 #ifdef notyet 540 struct ultrix_sys_quotactl_args *uap = v; 541 #endif 542 543 return EINVAL; 544 } 545 546 int 547 ultrix_sys_vhangup(p, v, retval) 548 struct proc *p; 549 void *v; 550 register_t *retval; 551 { 552 553 return 0; 554 } 555 556 557 /* 558 * RISC Ultrix cache control syscalls 559 */ 560 #ifdef __mips 561 int 562 ultrix_sys_cacheflush(p, v, retval) 563 register struct proc *p; 564 void *v; 565 register_t *retval; 566 { 567 register struct ultrix_sys_cacheflush_args /* { 568 syscallarg(void *) addr; 569 syscallarg(int) nbytes; 570 syscallarg(int) flag; 571 } */ *uap = v; 572 register vm_offset_t va = (vm_offset_t)SCARG(uap, addr); 573 register int nbytes = SCARG(uap, nbytes); 574 register int whichcache = SCARG(uap, whichcache); 575 576 return (mips_user_cacheflush(p, va, nbytes, whichcache)); 577 } 578 579 580 int 581 ultrix_sys_cachectl(p, v, retval) 582 register struct proc *p; 583 void *v; 584 register_t *retval; 585 { 586 register struct ultrix_sys_cachectl_args /* { 587 syscallarg(void *) addr; 588 syscallarg(int) nbytes; 589 syscallarg(int) cacheop; 590 } */ *uap = v; 591 register vm_offset_t va = (vm_offset_t)SCARG(uap, addr); 592 register int nbytes = SCARG(uap, nbytes); 593 register int cacheop = SCARG(uap, cacheop); 594 595 return mips_user_cachectl(p, va, nbytes, cacheop); 596 } 597 598 #endif /* __mips */ 599 600 601 int 602 ultrix_sys_exportfs(p, v, retval) 603 struct proc *p; 604 void *v; 605 register_t *retval; 606 { 607 #ifdef notyet 608 struct ultrix_sys_exportfs_args *uap = v; 609 #endif 610 611 /* 612 * XXX: should perhaps translate into a mount(2) 613 * with MOUNT_EXPORT? 614 */ 615 return 0; 616 } 617 618 int 619 ultrix_sys_sigpending(p, v, retval) 620 struct proc *p; 621 void *v; 622 register_t *retval; 623 { 624 struct ultrix_sys_sigpending_args *uap = v; 625 int mask = p->p_siglist & p->p_sigmask; 626 627 return (copyout((caddr_t)&mask, (caddr_t)SCARG(uap, mask), sizeof(int))); 628 } 629 630 int 631 ultrix_sys_sigcleanup(p, v, retval) 632 struct proc *p; 633 void *v; 634 register_t *retval; 635 { 636 struct ultrix_sys_sigcleanup_args *uap = v; 637 638 return sys_sigreturn(p, (struct sys_sigreturn_args *)uap, retval); 639 } 640 641 642 int 643 ultrix_sys_shmsys(p, v, retval) 644 struct proc *p; 645 void *v; 646 register_t *retval; 647 { 648 649 #ifdef SYSVSHM 650 651 /* Ultrix SVSHM weirndess: */ 652 struct ultrix_sys_shmsys_args *uap = v; 653 struct sys_shmat_args shmat_args; 654 struct sys_shmctl_args shmctl_args; 655 struct sys_shmdt_args shmdt_args; 656 struct sys_shmget_args shmget_args; 657 658 659 switch (SCARG(uap, shmop)) { 660 case 0: /* Ultrix shmat() */ 661 SCARG(&shmat_args, shmid) = SCARG(uap, a2); 662 SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a3); 663 SCARG(&shmat_args, shmflg) = SCARG(uap, a4); 664 return (sys_shmat(p, &shmat_args, retval)); 665 666 case 1: /* Ultrix shmctl() */ 667 SCARG(&shmctl_args, shmid) = SCARG(uap, a2); 668 SCARG(&shmctl_args, cmd) = SCARG(uap, a3); 669 SCARG(&shmctl_args, buf) = (struct shmid_ds *)SCARG(uap, a4); 670 return (sys_shmctl(p, &shmctl_args, retval)); 671 672 case 2: /* Ultrix shmdt() */ 673 SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a2); 674 return (sys_shmdt(p, &shmdt_args, retval)); 675 676 case 3: /* Ultrix shmget() */ 677 SCARG(&shmget_args, key) = SCARG(uap, a2); 678 SCARG(&shmget_args, size) = SCARG(uap, a3); 679 SCARG(&shmget_args, shmflg) = SCARG(uap, a4) 680 & (IPC_CREAT|IPC_EXCL|IPC_NOWAIT); 681 return (sys_shmget(p, &shmget_args, retval)); 682 683 default: 684 return (EINVAL); 685 } 686 #else 687 return (EOPNOTSUPP); 688 #endif /* SYSVSHM */ 689 } 690