1 /* $NetBSD: ultrix_misc.c,v 1.30 1997/04/06 23:26:53 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> 131 132 #include <sys/conf.h> /* iszerodev() */ 133 #include <sys/socketvar.h> /* sosetopt() */ 134 135 extern struct sysent ultrix_sysent[]; 136 extern char *ultrix_syscallnames[]; 137 138 /* 139 * Select the appropriate setregs callback for the target architecture. 140 */ 141 #ifdef mips 142 #define ULTRIX_EXEC_SETREGS cpu_exec_ecoff_setregs 143 #endif /* mips */ 144 145 #ifdef vax 146 #define ULTRIX_EXEC_SETREGS setregs 147 #endif /* mips */ 148 149 150 extern void ULTRIX_EXEC_SETREGS __P((struct proc *, struct exec_package *, 151 u_long, register_t *)); 152 extern char sigcode[], esigcode[]; 153 154 struct emul emul_ultrix = { 155 "ultrix", 156 NULL, 157 sendsig, 158 ULTRIX_SYS_syscall, 159 ULTRIX_SYS_MAXSYSCALL, 160 ultrix_sysent, 161 ultrix_syscallnames, 162 0, 163 copyargs, 164 ULTRIX_EXEC_SETREGS, 165 sigcode, 166 esigcode, 167 }; 168 169 #define GSI_PROG_ENV 1 170 171 int 172 ultrix_sys_getsysinfo(p, v, retval) 173 struct proc *p; 174 void *v; 175 register_t *retval; 176 { 177 struct ultrix_sys_getsysinfo_args *uap = v; 178 static short progenv = 0; 179 180 switch (SCARG(uap, op)) { 181 /* operations implemented: */ 182 case GSI_PROG_ENV: 183 if (SCARG(uap, nbytes) < sizeof(short)) 184 return EINVAL; 185 *retval = 1; 186 return (copyout(&progenv, SCARG(uap, buffer), sizeof(short))); 187 default: 188 *retval = 0; /* info unavail */ 189 return 0; 190 } 191 } 192 193 int 194 ultrix_sys_setsysinfo(p, v, retval) 195 struct proc *p; 196 void *v; 197 register_t *retval; 198 { 199 200 #ifdef notyet 201 struct ultrix_sys_setsysinfo_args *uap = v; 202 #endif 203 204 *retval = 0; 205 return 0; 206 } 207 208 int 209 ultrix_sys_waitpid(p, v, retval) 210 struct proc *p; 211 void *v; 212 register_t *retval; 213 { 214 struct ultrix_sys_waitpid_args *uap = v; 215 struct sys_wait4_args ua; 216 217 SCARG(&ua, pid) = SCARG(uap, pid); 218 SCARG(&ua, status) = SCARG(uap, status); 219 SCARG(&ua, options) = SCARG(uap, options); 220 SCARG(&ua, rusage) = 0; 221 222 return (sys_wait4(p, &ua, retval)); 223 } 224 225 int 226 ultrix_sys_wait3(p, v, retval) 227 struct proc *p; 228 void *v; 229 register_t *retval; 230 { 231 struct ultrix_sys_wait3_args *uap = v; 232 struct sys_wait4_args ua; 233 234 SCARG(&ua, pid) = -1; 235 SCARG(&ua, status) = SCARG(uap, status); 236 SCARG(&ua, options) = SCARG(uap, options); 237 SCARG(&ua, rusage) = SCARG(uap, rusage); 238 239 return (sys_wait4(p, &ua, retval)); 240 } 241 242 /* 243 * Ultrix binaries pass in FD_MAX as the first arg to select(). 244 * On Ultrix, FD_MAX is 4096, which is more than the NetBSD sys_select() 245 * can handle. 246 * Since we can't have more than the (native) FD_MAX descriptors open, 247 * limit nfds to at most FD_MAX. 248 */ 249 int 250 ultrix_sys_select(p, v, retval) 251 struct proc *p; 252 void *v; 253 register_t *retval; 254 { 255 struct sys_select_args *uap = v; 256 struct timeval atv; 257 int error; 258 259 /* Limit number of FDs selected on to the native maximum */ 260 261 if (SCARG(uap, nd) > FD_SETSIZE) 262 SCARG(uap, nd) = FD_SETSIZE; 263 264 /* Check for negative timeval */ 265 if (SCARG(uap, tv)) { 266 error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv, 267 sizeof(atv)); 268 if (error) 269 goto done; 270 #ifdef DEBUG 271 /* Ultrix clients sometimes give negative timeouts? */ 272 if (atv.tv_sec < 0 || atv.tv_usec < 0) 273 printf("ultrix select( %ld, %ld): negative timeout\n", 274 atv.tv_sec, atv.tv_usec); 275 /*tvp = (timeval *)STACKGAPBASE;*/ 276 #endif 277 278 } 279 error = sys_select(p, (void*) uap, retval); 280 if (error == EINVAL) 281 printf("ultrix select: bad args?\n"); 282 283 done: 284 return error; 285 } 286 287 #if defined(NFS) 288 int 289 async_daemon(p, v, retval) 290 struct proc *p; 291 void *v; 292 register_t *retval; 293 { 294 struct sys_nfssvc_args ouap; 295 296 SCARG(&ouap, flag) = NFSSVC_BIOD; 297 SCARG(&ouap, argp) = NULL; 298 299 return (sys_nfssvc(p, &ouap, retval)); 300 } 301 #endif /* NFS */ 302 303 304 #define SUN__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */ 305 306 int 307 ultrix_sys_mmap(p, v, retval) 308 register struct proc *p; 309 void *v; 310 register_t *retval; 311 { 312 register struct ultrix_sys_mmap_args *uap = v; 313 struct sys_mmap_args ouap; 314 register struct filedesc *fdp; 315 register struct file *fp; 316 register struct vnode *vp; 317 318 /* 319 * Verify the arguments. 320 */ 321 if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC)) 322 return (EINVAL); /* XXX still needed? */ 323 324 if ((SCARG(uap, flags) & SUN__MAP_NEW) == 0) 325 return (EINVAL); 326 327 SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUN__MAP_NEW; 328 SCARG(&ouap, addr) = SCARG(uap, addr); 329 330 if ((SCARG(&ouap, flags) & MAP_FIXED) == 0 && 331 SCARG(&ouap, addr) != 0 && 332 SCARG(&ouap, addr) < (caddr_t)round_page(p->p_vmspace->vm_daddr+MAXDSIZ)) 333 SCARG(&ouap, addr) = (caddr_t)round_page(p->p_vmspace->vm_daddr+MAXDSIZ); 334 335 SCARG(&ouap, len) = SCARG(uap, len); 336 SCARG(&ouap, prot) = SCARG(uap, prot); 337 SCARG(&ouap, fd) = SCARG(uap, fd); 338 SCARG(&ouap, pos) = SCARG(uap, pos); 339 340 /* 341 * Special case: if fd refers to /dev/zero, map as MAP_ANON. (XXX) 342 */ 343 fdp = p->p_fd; 344 if ((unsigned)SCARG(&ouap, fd) < fdp->fd_nfiles && /*XXX*/ 345 (fp = fdp->fd_ofiles[SCARG(&ouap, fd)]) != NULL && /*XXX*/ 346 fp->f_type == DTYPE_VNODE && /*XXX*/ 347 (vp = (struct vnode *)fp->f_data)->v_type == VCHR && /*XXX*/ 348 iszerodev(vp->v_rdev)) { /*XXX*/ 349 SCARG(&ouap, flags) |= MAP_ANON; 350 SCARG(&ouap, fd) = -1; 351 } 352 353 return (sys_mmap(p, &ouap, retval)); 354 } 355 356 int 357 ultrix_sys_setsockopt(p, v, retval) 358 struct proc *p; 359 void *v; 360 register_t *retval; 361 { 362 register struct ultrix_sys_setsockopt_args *uap = v; 363 struct file *fp; 364 struct mbuf *m = NULL; 365 int error; 366 367 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0) 368 return (error); 369 #define SO_DONTLINGER (~SO_LINGER) 370 if (SCARG(uap, name) == SO_DONTLINGER) { 371 m = m_get(M_WAIT, MT_SOOPTS); 372 mtod(m, struct linger *)->l_onoff = 0; 373 m->m_len = sizeof(struct linger); 374 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level), 375 SO_LINGER, m)); 376 } 377 if (SCARG(uap, level) == IPPROTO_IP) { 378 #define EMUL_IP_MULTICAST_IF 2 379 #define EMUL_IP_MULTICAST_TTL 3 380 #define EMUL_IP_MULTICAST_LOOP 4 381 #define EMUL_IP_ADD_MEMBERSHIP 5 382 #define EMUL_IP_DROP_MEMBERSHIP 6 383 static int ipoptxlat[] = { 384 IP_MULTICAST_IF, 385 IP_MULTICAST_TTL, 386 IP_MULTICAST_LOOP, 387 IP_ADD_MEMBERSHIP, 388 IP_DROP_MEMBERSHIP 389 }; 390 if (SCARG(uap, name) >= EMUL_IP_MULTICAST_IF && 391 SCARG(uap, name) <= EMUL_IP_DROP_MEMBERSHIP) { 392 SCARG(uap, name) = 393 ipoptxlat[SCARG(uap, name) - EMUL_IP_MULTICAST_IF]; 394 } 395 } 396 if (SCARG(uap, valsize) > MLEN) 397 return (EINVAL); 398 if (SCARG(uap, val)) { 399 m = m_get(M_WAIT, MT_SOOPTS); 400 error = copyin(SCARG(uap, val), mtod(m, caddr_t), 401 (u_int)SCARG(uap, valsize)); 402 if (error) { 403 (void) m_free(m); 404 return (error); 405 } 406 m->m_len = SCARG(uap, valsize); 407 } 408 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level), 409 SCARG(uap, name), m)); 410 } 411 412 struct ultrix_utsname { 413 char sysname[9]; 414 char nodename[9]; 415 char nodeext[65-9]; 416 char release[9]; 417 char version[9]; 418 char machine[9]; 419 }; 420 421 int 422 ultrix_sys_uname(p, v, retval) 423 struct proc *p; 424 void *v; 425 register_t *retval; 426 { 427 struct ultrix_sys_uname_args *uap = v; 428 struct ultrix_utsname sut; 429 extern char ostype[], machine[], osrelease[]; 430 431 bzero(&sut, sizeof(sut)); 432 433 bcopy(ostype, sut.sysname, sizeof(sut.sysname) - 1); 434 bcopy(hostname, sut.nodename, sizeof(sut.nodename)); 435 sut.nodename[sizeof(sut.nodename)-1] = '\0'; 436 bcopy(osrelease, sut.release, sizeof(sut.release) - 1); 437 bcopy("1", sut.version, sizeof(sut.version) - 1); 438 bcopy(machine, sut.machine, sizeof(sut.machine) - 1); 439 440 return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, name), 441 sizeof(struct ultrix_utsname)); 442 } 443 444 int 445 ultrix_sys_setpgrp(p, v, retval) 446 struct proc *p; 447 void *v; 448 register_t *retval; 449 { 450 struct ultrix_sys_setpgrp_args *uap = v; 451 452 /* 453 * difference to our setpgid call is to include backwards 454 * compatibility to pre-setsid() binaries. Do setsid() 455 * instead of setpgid() in those cases where the process 456 * tries to create a new session the old way. 457 */ 458 if (!SCARG(uap, pgid) && 459 (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid)) 460 return sys_setsid(p, uap, retval); 461 else 462 return sys_setpgid(p, uap, retval); 463 } 464 465 #if defined (NFSSERVER) 466 int 467 ultrix_sys_nfssvc(p, v, retval) 468 struct proc *p; 469 void *v; 470 register_t *retval; 471 { 472 473 #if 0 /* XXX */ 474 struct ultrix_sys_nfssvc_args *uap = v; 475 struct emul *e = p->p_emul; 476 struct sys_nfssvc_args outuap; 477 struct sockaddr sa; 478 int error; 479 480 bzero(&outuap, sizeof outuap); 481 SCARG(&outuap, fd) = SCARG(uap, fd); 482 SCARG(&outuap, mskval) = STACKGAPBASE; 483 SCARG(&outuap, msklen) = sizeof sa; 484 SCARG(&outuap, mtchval) = outuap.mskval + sizeof sa; 485 SCARG(&outuap, mtchlen) = sizeof sa; 486 487 bzero(&sa, sizeof sa); 488 if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen))) 489 return (error); 490 if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen))) 491 return (error); 492 493 return nfssvc(p, &outuap, retval); 494 #else 495 return (ENOSYS); 496 #endif 497 } 498 #endif /* NFSSERVER */ 499 500 struct ultrix_ustat { 501 daddr_t f_tfree; /* total free */ 502 ino_t f_tinode; /* total inodes free */ 503 char f_fname[6]; /* filsys name */ 504 char f_fpack[6]; /* filsys pack name */ 505 }; 506 507 int 508 ultrix_sys_ustat(p, v, retval) 509 struct proc *p; 510 void *v; 511 register_t *retval; 512 { 513 struct ultrix_sys_ustat_args *uap = v; 514 struct ultrix_ustat us; 515 int error; 516 517 bzero(&us, sizeof us); 518 519 /* 520 * XXX: should set f_tfree and f_tinode at least 521 * How do we translate dev -> fstat? (and then to ultrix_ustat) 522 */ 523 524 if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0) 525 return (error); 526 return 0; 527 } 528 529 int 530 ultrix_sys_quotactl(p, v, retval) 531 struct proc *p; 532 void *v; 533 register_t *retval; 534 { 535 536 #ifdef notyet 537 struct ultrix_sys_quotactl_args *uap = v; 538 #endif 539 540 return EINVAL; 541 } 542 543 int 544 ultrix_sys_vhangup(p, v, retval) 545 struct proc *p; 546 void *v; 547 register_t *retval; 548 { 549 550 return 0; 551 } 552 553 int 554 ultrix_sys_exportfs(p, v, retval) 555 struct proc *p; 556 void *v; 557 register_t *retval; 558 { 559 #ifdef notyet 560 struct ultrix_sys_exportfs_args *uap = v; 561 #endif 562 563 /* 564 * XXX: should perhaps translate into a mount(2) 565 * with MOUNT_EXPORT? 566 */ 567 return 0; 568 } 569 570 int 571 ultrix_sys_sigpending(p, v, retval) 572 struct proc *p; 573 void *v; 574 register_t *retval; 575 { 576 struct ultrix_sys_sigpending_args *uap = v; 577 int mask = p->p_siglist & p->p_sigmask; 578 579 return (copyout((caddr_t)&mask, (caddr_t)SCARG(uap, mask), sizeof(int))); 580 } 581 582 int 583 ultrix_sys_sigcleanup(p, v, retval) 584 struct proc *p; 585 void *v; 586 register_t *retval; 587 { 588 struct ultrix_sys_sigcleanup_args *uap = v; 589 590 return sys_sigreturn(p, (struct sys_sigreturn_args *)uap, retval); 591 } 592 593 int 594 ultrix_sys_sigreturn(p, v, retval) 595 struct proc *p; 596 void *v; 597 register_t *retval; 598 { 599 struct ultrix_sys_sigcleanup_args *uap = v; 600 601 #ifdef DEBUG 602 printf("ultrix sigreturn\n"); 603 #endif 604 return sys_sigreturn(p, (struct sys_sigreturn_args *)uap, retval); 605 } 606 607 ultrix_sys_shmsys(p, v, retval) 608 struct proc *p; 609 void *v; 610 register_t *retval; 611 { 612 613 #ifdef SYSVSHM 614 615 /* Ultrix SVSHM weirndess: */ 616 struct ultrix_sys_shmsys_args *uap = v; 617 struct sys_shmat_args shmat_args; 618 struct sys_shmctl_args shmctl_args; 619 struct sys_shmdt_args shmdt_args; 620 struct sys_shmget_args shmget_args; 621 622 623 switch (SCARG(uap, shmop)) { 624 case 0: /* Ultrix shmat() */ 625 SCARG(&shmat_args, shmid) = SCARG(uap, a2); 626 SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a3); 627 SCARG(&shmat_args, shmflg) = SCARG(uap, a4); 628 return (sys_shmat(p, &shmat_args, retval)); 629 630 case 1: /* Ultrix shmctl() */ 631 SCARG(&shmctl_args, shmid) = SCARG(uap, a2); 632 SCARG(&shmctl_args, cmd) = SCARG(uap, a3); 633 SCARG(&shmctl_args, buf) = (struct shmid_ds *)SCARG(uap, a4); 634 return (sys_shmctl(p, &shmctl_args, retval)); 635 636 case 2: /* Ultrix shmdt() */ 637 SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a2); 638 return (sys_shmdt(p, &shmdt_args, retval)); 639 640 case 3: /* Ultrix shmget() */ 641 SCARG(&shmget_args, key) = SCARG(uap, a2); 642 SCARG(&shmget_args, size) = SCARG(uap, a3); 643 SCARG(&shmget_args, shmflg) = SCARG(uap, a4) 644 & (IPC_CREAT|IPC_EXCL|IPC_NOWAIT); 645 return (sys_shmget(p, &shmget_args, retval)); 646 647 default: 648 return (EINVAL); 649 } 650 } 651 #endif /* SYSVSHM */ 652 653 return (EOPNOTSUPP); 654 } 655