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