ibcs2_misc.c revision 3584
1/*- 2 * Copyright (c) 1994 S�ren Schmidt 3 * Copyright (c) 1994 Sean Eric Fagan 4 * All rights reserved. 5 * 6 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer 14 * in this position and unchanged. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * $Id: ibcs2_misc.c,v 1.16 1994/10/13 23:10:58 sos Exp $ 39 */ 40 41#include <i386/ibcs2/ibcs2.h> 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/proc.h> 45#include <sys/exec.h> 46#include <sys/sysent.h> 47#include <sys/ioctl.h> 48#include <sys/resource.h> 49#include <sys/resourcevar.h> 50#include <sys/stat.h> 51#include <sys/time.h> 52#include <sys/times.h> 53#include <sys/unistd.h> 54#include <sys/wait.h> 55#include <vm/vm.h> 56#include <machine/cpu.h> 57#include <machine/psl.h> 58#include <machine/reg.h> 59 60int ibcs2_trace = 0; 61 62struct ibcs2_traceemu_args { 63 int options; 64}; 65 66int 67ibcs2_traceemu(struct proc *p, struct ibcs2_traceemu_args *args, int *retval) 68{ 69 *retval = ibcs2_trace; 70 ibcs2_trace = args->options; 71 return 0; 72} 73 74int 75ibcs2_access(struct proc *p, void *args, int *retval) 76{ 77 if (ibcs2_trace & IBCS2_TRACE_MISC) 78 printf("IBCS2: 'access'\n"); 79 return access(p, args, retval); 80} 81 82struct ibcs2_alarm_args { 83 unsigned int secs; 84}; 85 86int 87ibcs2_alarm(struct proc *p, struct ibcs2_alarm_args *args, int *retval) 88{ 89 extern struct timeval time; 90 struct itimerval it, oit; 91 int s; 92 93 if (ibcs2_trace & IBCS2_TRACE_MISC) 94 printf("IBCS2: 'alarm' secs=%d\n", args->secs); 95 it.it_value.tv_sec = (long)args->secs; 96 it.it_value.tv_usec = 0; 97 it.it_interval.tv_sec = 0; 98 it.it_interval.tv_usec = 0; 99 s = splclock(); 100 oit = p->p_realtimer; 101 if (timerisset(&oit.it_value)) 102 if (timercmp(&oit.it_value, &time, <)) 103 timerclear(&oit.it_value); 104 else 105 timevalsub(&oit.it_value, &time); 106 splx(s); 107 if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) 108 return EINVAL; 109 s = splclock(); 110 untimeout(realitexpire, (caddr_t)p); 111 if (timerisset(&it.it_value)) { 112 timevaladd(&it.it_value, &time); 113 timeout(realitexpire, (caddr_t)p, hzto(&it.it_value)); 114 } 115 p->p_realtimer = it; 116 splx(s); 117 if (oit.it_value.tv_usec) 118 oit.it_value.tv_sec++; 119 *retval = oit.it_value.tv_sec; 120 return 0; 121} 122 123struct ibcs2_break_args { 124 char *dsend; 125}; 126 127int 128ibcs2_break(struct proc *p, struct ibcs2_break_args *args, int *retval) 129{ 130 struct vmspace *vm = p->p_vmspace; 131 vm_offset_t new, old; 132 int rv, diff; 133 extern int swap_pager_full; 134 135 if (ibcs2_trace & IBCS2_TRACE_MISC) 136 printf("IBCS2: 'break' dsend=%x\n", 137 (unsigned int)args->dsend); 138 139 if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr) 140 return EINVAL; 141 if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr) 142 > p->p_rlimit[RLIMIT_DATA].rlim_cur) 143 return ENOMEM; 144 145 old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize); 146 new = round_page((vm_offset_t)args->dsend); 147 148 diff = new - old; 149 if (diff > 0) { 150 if (swap_pager_full) { 151 return ENOMEM; 152 } 153 rv = vm_allocate(&vm->vm_map, &old, diff, FALSE); 154 if (rv != KERN_SUCCESS) { 155 return ENOMEM; 156 } 157 vm->vm_dsize += btoc(diff); 158 } 159 else if (diff < 0) { 160 diff = -diff; 161 rv = vm_deallocate(&vm->vm_map, new, diff); 162 if (rv != KERN_SUCCESS) 163 return ENOMEM; 164 vm->vm_dsize -= btoc(diff); 165 } 166 return 0; 167} 168 169int 170ibcs2_chdir(struct proc *p, void *args, int *retval) 171{ 172 if (ibcs2_trace & IBCS2_TRACE_MISC) 173 printf("IBCS2: 'chdir'\n"); 174 return chdir(p, args, retval); 175} 176 177int 178ibcs2_chmod(struct proc *p, void *args, int *retval) 179{ 180 if (ibcs2_trace & IBCS2_TRACE_MISC) 181 printf("IBCS2: 'chmod'\n"); 182 return chmod(p, args, retval); 183} 184 185int 186ibcs2_chown(struct proc *p, void *args, int *retval) 187{ 188 if (ibcs2_trace & IBCS2_TRACE_MISC) 189 printf("IBCS2: 'chown'\n"); 190 return chown(p, args, retval); 191} 192 193int 194ibcs2_chroot(struct proc *p, void *args, int *retval) 195{ 196 if (ibcs2_trace & IBCS2_TRACE_MISC) 197 printf("IBCS2: 'chroot'\n"); 198 return chroot(p, args, retval); 199} 200 201struct ibcs2_close_args { 202 int fd; 203}; 204 205int 206ibcs2_close(struct proc *p, struct ibcs2_close_args *args, int *retval) 207{ 208 if (ibcs2_trace & IBCS2_TRACE_MISC) 209 printf("IBCS2: 'close' fd=%d\n", args->fd); 210 return close(p, args, retval); 211} 212 213struct exec_args { 214 char *name; 215 char **argv; 216}; 217 218int 219ibcs2_exec(struct proc *p, struct exec_args *args, int *retval) 220{ 221 struct execve_args { 222 char *name; 223 char **argv; 224 char **envp; 225 } execve_args; 226 227 if (ibcs2_trace & IBCS2_TRACE_MISC) 228 printf("IBCS2: 'exec' name=%s\n", args->name); 229 execve_args.name = args->name; 230 execve_args.argv = args->argv; 231 execve_args.envp = 0; 232 return execve(p, &execve_args, retval); 233} 234 235struct ibcs2_exece_args { 236 char *name; 237 char **argv; 238 char **envp; 239}; 240 241int 242ibcs2_exece(struct proc *p, struct ibcs2_exece_args *args, int *retval) 243{ 244 if (ibcs2_trace & IBCS2_TRACE_MISC) 245 printf("IBCS2: 'exece' name=%s\n", args->name); 246 return execve(p, args, retval); 247} 248 249int 250ibcs2_exit(struct proc *p, void *args, int *retval) 251{ 252 if (ibcs2_trace & IBCS2_TRACE_MISC) 253 printf("IBCS2: 'exit'\n"); 254 return exit(p, args, retval); 255} 256 257int 258ibcs2_fork(struct proc *p, void *args, int *retval) 259{ 260 if (ibcs2_trace & IBCS2_TRACE_MISC) 261 printf("IBCS2: 'fork'\n"); 262 return fork(p, args, retval); 263} 264 265int 266ibcs2_fsync(struct proc *p, void *args, int *retval) 267{ 268 if (ibcs2_trace & IBCS2_TRACE_MISC) 269 printf("IBCS2: 'fsync'\n"); 270 return fsync(p, args, retval); 271} 272 273int 274ibcs2_getgid(struct proc *p, void *args, int *retval) 275{ 276 if (ibcs2_trace & IBCS2_TRACE_MISC) 277 printf("IBCS2: 'getgid'\n"); 278 return getgid(p, args, retval); 279} 280 281struct ibcs2_getgroups_args { 282 int gidsetsize; 283 ibcs2_gid_t *gidset; 284}; 285 286int 287ibcs2_getgroups(struct proc *p, struct ibcs2_getgroups_args *args, int *retval) 288{ 289 struct getgroups_args { 290 u_int gidsetsize; 291 gid_t *gidset; 292 } tmp; 293 ibcs2_gid_t *ibcs2_gidset; 294 int i, error; 295 296 if (ibcs2_trace & IBCS2_TRACE_MISC) 297 printf("IBCS2: 'getgroups'\n"); 298 299 tmp.gidsetsize = args->gidsetsize; 300 tmp.gidset = (gid_t *)UA_ALLOC(); 301 ibcs2_gidset = (ibcs2_gid_t *)&tmp.gidset[NGROUPS_MAX]; 302 if (error = getgroups(p, &tmp, retval)) 303 return error; 304 for (i = 0; i < retval[0]; i++) 305 ibcs2_gidset[i] = (ibcs2_gid_t)tmp.gidset[i]; 306 return copyout((caddr_t)ibcs2_gidset, (caddr_t)args->gidset, 307 sizeof(ibcs2_gid_t) * retval[0]); 308} 309 310int 311ibcs2_getpid(struct proc *p, void *args, int *retval) 312{ 313 if (ibcs2_trace & IBCS2_TRACE_MISC) 314 printf("IBCS2: 'getpid'\n"); 315 return getpid(p, args, retval); 316} 317 318int 319ibcs2_getuid(struct proc *p, void *args, int *retval) 320{ 321 if (ibcs2_trace & IBCS2_TRACE_MISC) 322 printf("IBCS2: 'getuid'\n"); 323 return getuid(p, args, retval); 324} 325 326struct gtime_args { 327 long *timeptr; 328}; 329 330int 331ibcs2_gtime(struct proc *p, struct gtime_args *args, int *retval) 332{ 333 int error = 0; 334 struct timeval tv; 335 336 if (ibcs2_trace & IBCS2_TRACE_MISC) 337 printf("IBCS2: 'gtime'\n"); 338 microtime(&tv); 339 *retval = tv.tv_sec; 340 if (args) 341 (long)args->timeptr = tv.tv_sec; 342 return error; 343} 344 345int 346ibcs2_link(struct proc *p, void *args, int *retval) 347{ 348 if (ibcs2_trace & IBCS2_TRACE_MISC) 349 printf("IBCS2: 'link'\n"); 350 return link(p, args, retval); 351} 352 353int 354ibcs2_mkdir(struct proc *p, void *args, int *retval) 355{ 356 if (ibcs2_trace & IBCS2_TRACE_MISC) 357 printf("IBCS2: 'mkdir'\n"); 358 return mkdir(p, args, retval); 359} 360 361struct ibcs2_mknod_args { 362 char *fname; 363 int fmode; 364 ibcs2_dev_t dev; 365}; 366 367int 368ibcs2_mknod(struct proc *p, struct ibcs2_mknod_args *args, int *retval) 369{ 370 if (ibcs2_trace & IBCS2_TRACE_MISC) 371 printf("IBCS2: 'mknod'\n"); 372 if (S_ISFIFO(args->fmode)) 373 return mkfifo(p, args, retval); 374 return mknod(p, args, retval); 375} 376 377struct ibcs2_nice_args { 378 int niceval; 379}; 380 381int 382ibcs2_nice(struct proc *p, struct ibcs2_nice_args *args, int *retval) 383{ 384 int error; 385 386 if (ibcs2_trace & IBCS2_TRACE_MISC) 387 printf("IBCS2: 'nice'\n"); 388 error = donice(p, p, args->niceval); 389 *retval = p->p_nice; 390 return error; 391} 392 393struct ibcs2_pathconf_args { 394 long unused; 395 int cmd; 396}; 397int 398ibcs2_pathconf(struct proc *p, struct ibcs2_pathconf_args *args, int *retval) 399{ 400 if (ibcs2_trace & IBCS2_TRACE_MISC) 401 printf("IBCS2: '(f)pathconf'\n"); 402 switch (args->cmd) { 403 case 0: /* _PC_LINK_MAX */ 404 *retval = (LINK_MAX); 405 break; 406 case 1: /* _PC_MAX_CANON */ 407 *retval = (MAX_CANON); 408 break; 409 case 2: /* _PC_MAX_INPUT */ 410 *retval = (MAX_INPUT); 411 break; 412 case 5: /* _PC_PATH_MAX */ 413 *retval = (PATH_MAX); 414 break; 415 case 8: /* _PC_VDISABLE */ 416 *retval = (_POSIX_VDISABLE); 417 break; 418 case 3: /* _PC_NAME_MAX */ 419 *retval = (NAME_MAX); 420 break; 421 case 4: /* _PC_PATH_MAX */ 422 *retval = (PATH_MAX); 423 break; 424 case 6: /* _PC_CHOWN_RESTRICTED */ 425#ifdef _POSIX_CHOWN_RESTRICTED 426 *retval = _POSIX_CHOWN_RESTRICTED; 427#else 428 *retval = (0); 429#endif 430 break; 431 case 7: /* _PC_NO_TRUNC */ 432#ifdef _POSIX_NO_TRUNC 433 *retval = _POSIX_NO_TRUNC; 434#else 435 *retval = (1); 436#endif 437 break; 438 default: 439 *retval = -1; 440 return EINVAL; 441 } 442 return 0; 443} 444 445int 446ibcs2_pause(struct proc *p, void *args, int *retval) 447{ 448 int mask = 0; 449 450 if (ibcs2_trace & IBCS2_TRACE_MISC) 451 printf("IBCS2: 'pause'\n"); 452 return sigsuspend(p, &mask, retval); 453} 454 455int 456ibcs2_pipe(struct proc *p, void *args, int *retval) 457{ 458 if (ibcs2_trace & IBCS2_TRACE_MISC) 459 printf("IBCS2: 'pipe'\n"); 460 return pipe(p, args, retval); 461} 462 463struct ibcs2_poll { 464 int fd; 465 short events; 466 short revents; 467}; 468 469struct ibcs2_poll_args { 470 struct ibcs2_poll *fds; 471 unsigned long nfds; 472 int timeout; 473}; 474 475int 476ibcs2_poll(struct proc *p, struct ibcs2_poll_args *args, int *retval) 477{ 478 struct ibcs2_poll conv; 479 fd_set *readfds, *writefds, *exceptfds; 480 struct timeval *timeout; 481 struct select_args { 482 u_int nd; 483 fd_set *in, *ou, *ex; 484 struct timeval *tv; 485 } tmp_select; 486 int i, error; 487 488 if (ibcs2_trace & IBCS2_TRACE_MISC) 489 printf("IBCS2: 'poll'\n"); 490 if (args->nfds > FD_SETSIZE) 491 return EINVAL; 492 readfds = (fd_set *)UA_ALLOC(); 493 FD_ZERO(readfds); 494 writefds = (fd_set *)UA_ALLOC() + sizeof(fd_set *); 495 FD_ZERO(writefds); 496 exceptfds = (fd_set *)UA_ALLOC() + 2*sizeof(fd_set *); 497 FD_ZERO(exceptfds); 498 timeout = (struct timeval *)UA_ALLOC() + 3*sizeof(fd_set *); 499 if (args->timeout == -1) 500 timeout = NULL; 501 else { 502 timeout->tv_usec = (args->timeout % 1000)*1000; 503 timeout->tv_sec = args->timeout / 1000; 504 } 505 tmp_select.nd = 0; 506 tmp_select.in = readfds; 507 tmp_select.ou = writefds; 508 tmp_select.ex = exceptfds; 509 tmp_select.tv = timeout; 510 for (i = 0; i < args->nfds; i++) { 511 if (error = copyin(args->fds + i*sizeof(struct ibcs2_poll), 512 &conv, sizeof(conv))) 513 return error; 514 conv.revents = 0; 515 if (conv.fd < 0 || conv.fd > FD_SETSIZE) 516 continue; 517 if (conv.fd >= tmp_select.nd) 518 tmp_select.nd = conv.fd + 1; 519 if (conv.events & IBCS2_READPOLL) 520 FD_SET(conv.fd, readfds); 521 if (conv.events & IBCS2_WRITEPOLL) 522 FD_SET(conv.fd, writefds); 523 FD_SET(conv.fd, exceptfds); 524 } 525 if (error = select(p, &tmp_select, retval)) 526 return error; 527 if (*retval == 0) 528 return 0; 529 *retval = 0; 530 for (*retval = 0, i = 0; i < args->nfds; i++) { 531 copyin(args->fds + i*sizeof(struct ibcs2_poll), 532 &conv, sizeof(conv)); 533 conv.revents = 0; 534 if (conv.fd < 0 || conv.fd > FD_SETSIZE) 535 /* should check for open as well */ 536 conv.revents |= IBCS2_POLLNVAL; 537 else { 538 if (FD_ISSET(conv.fd, readfds)) 539 conv.revents |= IBCS2_POLLIN; 540 if (FD_ISSET(conv.fd, writefds)) 541 conv.revents |= IBCS2_POLLOUT; 542 if (FD_ISSET(conv.fd, exceptfds)) 543 conv.revents |= IBCS2_POLLERR; 544 if (conv.revents) 545 ++*retval; 546 } 547 if (error = copyout(&conv, 548 args->fds + i*sizeof(struct ibcs2_poll), 549 sizeof(conv))) 550 return error; 551 } 552 return 0; 553} 554 555struct ibcs2_procids_args { 556 int req; 557 int eax; 558}; 559 560int 561ibcs2_procids(struct proc *p, struct ibcs2_procids_args *args, int *retval) 562{ 563 if (ibcs2_trace & IBCS2_TRACE_MISC) 564 printf("IBCS2: 'procids' request=%d, eax=%x\n", 565 args->req, args->eax); 566 switch (args->req) { 567 case 0: /* getpgrp */ 568 return getpgrp(p, args, retval); 569 case 1: /* setpgrp */ 570 { 571 struct setpgid_args { 572 int pid; 573 int pgid; 574 } tmp; 575 tmp.pid = tmp.pgid = 0; 576 return setpgid(p, &tmp, retval); 577 } 578 case 2: /* setpgid */ 579 return setpgid(p, args, retval); 580 case 3: /* setsid */ 581 return setsid(p, args, retval); 582 default: 583 return EINVAL; 584 } 585} 586 587int 588ibcs2_profil(struct proc *p, void *args, int *retval) 589{ 590 if (ibcs2_trace & IBCS2_TRACE_MISC) 591 printf("IBCS2: 'profil'\n"); 592 return profil(p, args, retval); 593} 594 595int 596ibcs2_ptrace(struct proc *p, void *args, int *retval) 597{ 598 if (ibcs2_trace & IBCS2_TRACE_MISC) 599 printf("IBCS2: 'ptrace'\n"); 600 return ptrace(p, args, retval); 601} 602 603int 604ibcs2_readlink(struct proc *p, void *args, int *retval) 605{ 606 if (ibcs2_trace & IBCS2_TRACE_MISC) 607 printf("IBCS2: 'readlink'\n"); 608 return readlink(p, args, retval); 609} 610 611int 612ibcs2_rename(struct proc *p, void *args, int *retval) 613{ 614 if (ibcs2_trace & IBCS2_TRACE_MISC) 615 printf("IBCS2: 'rename'\n"); 616 return rename(p, args, retval); 617} 618 619int 620ibcs2_rmdir(struct proc *p, void *args, int *retval) 621{ 622 if (ibcs2_trace & IBCS2_TRACE_MISC) 623 printf("IBCS2: 'rmdir'\n"); 624 return rmdir(p, args, retval); 625} 626 627struct ibcs2_secure_args { 628 int cmd; 629 int arg1; 630 int arg2; 631 int arg3; 632 int arg4; 633 int arg5; 634}; 635 636int 637ibcs2_secure(struct proc *p, struct ibcs2_secure_args *args, int *retval) 638{ 639 struct trapframe *tf = (struct trapframe *)p->p_md.md_regs; 640 641 if (ibcs2_trace & IBCS2_TRACE_MISC) 642 printf("IBCS2: 'secure'\n"); 643 644 switch (args->cmd) { 645 646 case 1: /* get login uid */ 647 *retval = p->p_ucred->cr_uid; 648 return EPERM; 649 650 case 2: /* set login uid */ 651 652 default: 653 printf("IBCS2: 'secure' cmd=%d not implemented\n",args->cmd); 654 } 655 return EINVAL; 656} 657 658struct ibcs2_setgid_args { 659 ibcs2_gid_t gid; 660}; 661 662int 663ibcs2_setgid(struct proc *p, struct ibcs2_setgid_args *args, int *retval) 664{ 665 struct setgid_args { 666 gid_t gid; 667 } tmp; 668 669 if (ibcs2_trace & IBCS2_TRACE_MISC) 670 printf("IBCS2: 'setgid'\n"); 671 tmp.gid = (gid_t) args->gid; 672 return setgid(p, &tmp, retval); 673} 674 675struct ibcs2_setgroups_args { 676 int gidsetsize; 677 ibcs2_gid_t *gidset; 678}; 679 680int 681ibcs2_setgroups(struct proc *p, struct ibcs2_setgroups_args *args, int *retval) 682{ 683 struct setgroups_args { 684 u_int gidsetsize; 685 gid_t *gidset; 686 } tmp; 687 ibcs2_gid_t *ibcs2_gidset; 688 int i, error; 689 690 if (ibcs2_trace & IBCS2_TRACE_MISC) 691 printf("IBCS2: 'setgroups'\n"); 692 tmp.gidsetsize = args->gidsetsize; 693 tmp.gidset = (gid_t *)UA_ALLOC(); 694 ibcs2_gidset = (ibcs2_gid_t *)&tmp.gidset[NGROUPS_MAX]; 695 if (error = copyin((caddr_t)args->gidset, (caddr_t)ibcs2_gidset, 696 sizeof(ibcs2_gid_t) * tmp.gidsetsize)) 697 return error; 698 for (i = 0; i < tmp.gidsetsize; i++) 699 tmp.gidset[i] = (gid_t)ibcs2_gidset[i]; 700 return setgroups(p, &tmp, retval); 701} 702 703struct ibcs2_setuid_args { 704 ibcs2_uid_t uid; 705}; 706 707int 708ibcs2_setuid(struct proc *p, struct ibcs2_setuid_args *args, int *retval) 709{ 710 struct setuid_args { 711 uid_t uid; 712 } tmp; 713 714 if (ibcs2_trace & IBCS2_TRACE_MISC) 715 printf("IBCS2: 'setuid'\n"); 716 tmp.uid = (uid_t) args->uid; 717 return setuid(p, &tmp, retval); 718} 719 720int 721ibcs2_smount(struct proc *p, void *args, int *retval) 722{ 723 if (ibcs2_trace & IBCS2_TRACE_MISC) 724 printf("IBCS2: 'smount'\n"); 725 return mount(p, args, retval); 726} 727 728struct ibcs2_stime_args { 729 long *timeptr; 730}; 731 732int 733ibcs2_stime(struct proc *p, struct ibcs2_stime_args *args, int *retval) 734{ 735 int error; 736 737 if (ibcs2_trace & IBCS2_TRACE_MISC) 738 printf("IBCS2: 'stime'\n"); 739 if (error = suser(p->p_ucred, &p->p_acflag)) 740 return error; 741 if (args->timeptr) { 742#if 0 743 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 744 boottime.tv_sec += (long)args->timeptr - time.tv_sec; 745 s = splhigh(); 746 time.tv_sec = (long)args->timeptr; 747 time.tv_usec = 0; 748 splx(s); 749 resettodr(); 750#else 751 printf("IBCS2: trying to set system time %d\n", 752 (long)args->timeptr); 753#endif 754 } 755 return 0; 756} 757 758int 759ibcs2_sumount(struct proc *p, void *args, int *retval) 760{ 761 if (ibcs2_trace & IBCS2_TRACE_MISC) 762 printf("IBCS2: 'sumount'\n"); 763 return unmount(p, args, retval); 764} 765 766int 767ibcs2_symlink(struct proc *p, void *args, int *retval) 768{ 769 if (ibcs2_trace & IBCS2_TRACE_MISC) 770 printf("IBCS2: 'symlink'\n"); 771 return symlink(p, args, retval); 772} 773 774int 775ibcs2_sync(struct proc *p, void *args, int *retval) 776{ 777 if (ibcs2_trace & IBCS2_TRACE_MISC) 778 printf("IBCS2: 'sync'\n"); 779 return sync(p, args, retval); 780} 781 782int 783ibcs2_sysacct(struct proc *p, void *args, int *retval) 784{ 785 if (ibcs2_trace & IBCS2_TRACE_MISC) 786 printf("IBCS2: 'sysacct'\n"); 787 return acct(p, args, retval); 788} 789 790struct ibcs2_tms { 791 long tms_utime; 792 long tms_stime; 793 long tms_cutime; 794 long tms_cstime; 795}; 796 797int 798ibcs2_times(struct proc *p, struct ibcs2_tms *args, int *retval) 799{ 800 extern int hz; 801 struct timeval tv; 802 struct ibcs2_tms tms; 803 804 if (ibcs2_trace & IBCS2_TRACE_MISC) 805 printf("IBCS2: 'times'\n"); 806 tms.tms_utime = p->p_uticks; 807 tms.tms_stime = p->p_sticks; 808 tms.tms_cutime = p->p_stats->p_cru.ru_utime.tv_sec * hz + 809 ((p->p_stats->p_cru.ru_utime.tv_usec * hz)/1000000); 810 tms.tms_cstime = p->p_stats->p_cru.ru_stime.tv_sec * hz + 811 ((p->p_stats->p_cru.ru_stime.tv_usec * hz)/1000000); 812 microtime(&tv); 813 *retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000; 814 return (copyout((caddr_t)&tms, 815 (caddr_t)args->tms_utime, 816 sizeof(struct ibcs2_tms))); 817} 818 819struct ibcs2_ulimit_args { 820 int cmd; 821 long limit; 822}; 823 824int 825ibcs2_ulimit(struct proc *p, struct ibcs2_ulimit_args *args, int *retval) 826{ 827 if (ibcs2_trace & IBCS2_TRACE_MISC) 828 printf("IBCS2: 'ulimit'\n"); 829 switch (args->cmd) { 830 case IBCS2_GETFSIZE: 831 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur; 832 return 0; 833 834 case IBCS2_SETFSIZE: 835 return EINVAL; 836 837 case IBCS2_GETPSIZE: 838 *retval = p->p_rlimit[RLIMIT_RSS].rlim_cur; 839 return 0; 840 case IBCS2_GETMOPEN: 841 *retval = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 842 return 0; 843 } 844 return EINVAL; 845} 846 847int 848ibcs2_umask(struct proc *p, void *args, int *retval) 849{ 850 if (ibcs2_trace & IBCS2_TRACE_MISC) 851 printf("IBCS2: 'umask'\n"); 852 return umask(p, args, retval); 853} 854 855int 856ibcs2_unlink(struct proc *p, void *args, int *retval) 857{ 858 if (ibcs2_trace & IBCS2_TRACE_MISC) 859 printf("IBCS2: 'unlink'\n"); 860 return unlink(p, args, retval); 861} 862 863struct ibcs2_utime_args { 864 char *fname; 865 ibcs2_time_t *timeptr; 866}; 867 868int 869ibcs2_utime(struct proc *p, struct ibcs2_utime_args *args, int *retval) 870{ 871 struct bsd_utimes_args { 872 char *fname; 873 struct timeval *tptr; 874 } bsdutimes; 875 struct timeval tv; 876 877 if (ibcs2_trace & IBCS2_TRACE_MISC) 878 printf("IBCS2: 'utime'\n"); 879 tv.tv_sec = (long)args->timeptr; 880 tv.tv_usec = 0; 881 bsdutimes.tptr = &tv; 882 bsdutimes.fname = args->fname; 883 return utimes(p, &bsdutimes, retval); 884} 885 886struct ibcs2_utssys_args { 887 char *buf; 888 int mv; 889 int cmd; 890}; 891 892int 893ibcs2_utssys(struct proc *p, struct ibcs2_utssys_args *args, int *retval) 894{ 895 struct ibcs2_utsname { 896 char sysname[9]; 897 char nodename[9]; 898 char release[9]; 899 char version[9]; 900 char machine[9]; 901 } ibcs2_uname; 902 extern char ostype[], hostname[], osrelease[], machine[]; 903 904 if (ibcs2_trace & IBCS2_TRACE_MISC) 905 printf("IBCS2: 'utssys' cmd=%d\n", args->cmd); 906 switch(args->cmd) { 907 case 0: /* uname */ 908 bzero(&ibcs2_uname, sizeof(struct ibcs2_utsname)); 909 strncpy(ibcs2_uname.sysname, ostype, 8); 910 strncpy(ibcs2_uname.nodename, hostname, 8); 911 strncpy(ibcs2_uname.release, osrelease, 8); 912 strncpy(ibcs2_uname.version, version, 8); 913 strncpy(ibcs2_uname.machine, machine, 8); 914 return (copyout((caddr_t)&ibcs2_uname, 915 (caddr_t)args->buf, 916 sizeof(struct ibcs2_utsname))); 917 918 case 2: /* ustat */ 919 printf("IBCS2: utssys(ustat) not implemented yet\n"); 920 return EINVAL; 921 922 case 1: /* umask, obsolete */ 923 default: 924 printf("IBCS2: 'utssys cmd (%d) not implemented yet'\n", 925 args->cmd); 926 return EINVAL; 927 } 928} 929 930int 931ibcs2_wait(struct proc *p, void *args, int *retval) 932{ 933 struct trapframe *tf = (struct trapframe *)p->p_md.md_regs; 934 struct ibcs2_waitpid_args { 935 int pid; 936 int *status; 937 int options; 938 } *t = args; 939 struct wait4_args { 940 int pid; 941 int *status; 942 int options; 943 struct rusage *rusage; 944 int compat; 945 } tmp; 946 947 tmp.compat = 1; 948 tmp.rusage = 0; 949 if (ibcs2_trace & IBCS2_TRACE_MISC) 950 printf("IBCS2: 'wait'\n"); 951 952 if ((tf->tf_eflags & (PSL_Z|PSL_PF|PSL_N|PSL_V)) 953 == (PSL_Z|PSL_PF|PSL_N|PSL_V)) { 954 tmp.pid = t->pid; 955 tmp.status = t->status; 956 tmp.options = 0; 957 if (t->options & 02) 958 tmp.options |= WUNTRACED; 959 if (t->options & 01) 960 tmp.options |= WNOHANG; 961 tmp.options = t->options; 962 } else { 963 tmp.pid = WAIT_ANY; 964 tmp.status = (int*)t->pid; 965 tmp.options = 0; 966 } 967 return wait1(p, &tmp, retval); 968} 969