|
|
1.1 ! root 1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/sys1.c,v 1.4 91/07/24 07:52:21 bin Exp Locker: bin $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * General system calls. ! 18: * ! 19: * $Log: sys1.c,v $ ! 20: * Revision 1.4 91/07/24 07:52:21 bin ! 21: * update prov by hal ! 22: * ! 23: * ! 24: * Revision 1.1 88/03/24 16:14:27 src ! 25: * Initial revision ! 26: * ! 27: * 87/11/05 Allan Cornish /usr/src/sys/coh/sys1.c ! 28: * New seg struct now used to allow extended addressing. ! 29: * ! 30: * 87/10/21 Allan Cornish /usr/src/sys/coh/sys1.c ! 31: * ukill() no longer signals kernel processes if pid is -1. ! 32: * usload() changed to new loadable driver format. ! 33: * ! 34: * 87/08/14 Allan Cornish /usr/src/sys/coh/sys1.c ! 35: * utick() system call added. Returns elapsed clock ticks since system startup. ! 36: * ! 37: * 87/07/23 Allan Cornish /usr/src/sys/coh/sys1.c ! 38: * ualarm2() now takes the delay interval as a long instead of an unsigned. ! 39: * ! 40: * 87/07/08 Allan Cornish /usr/src/sys/coh/sys1.c ! 41: * ualarm() modified to use timed functions to send alarm signal. ! 42: * ualarm2() added to allow alarm times in clock ticks rather than seconds. ! 43: * ! 44: * 85/07/25 Allan Cornish ! 45: * ukill() modified to allow a signal of 0 to check process existence. ! 46: * ! 47: * 85/07/9 Allan Cornish ! 48: * ukill() modified to allow signals to be sent to other process groups. ! 49: * usetpgrp() modified to be System V compatible (group set to pid). ! 50: * ugetpgrp() system call added. ! 51: */ ! 52: #include <sys/coherent.h> ! 53: #include <acct.h> ! 54: #include <sys/con.h> ! 55: #include <errno.h> ! 56: #include <sys/proc.h> ! 57: #include <sys/sched.h> ! 58: #include <sys/seg.h> ! 59: #include <signal.h> ! 60: #include <sys/timeb.h> ! 61: #include <sys/times.h> ! 62: #include <sys/uproc.h> ! 63: ! 64: /* ! 65: * Send alarm signal to specified process - function timed by ualarm() ! 66: */ ! 67: static ! 68: sigalrm( pp ) ! 69: register PROC * pp; ! 70: { ! 71: sendsig( SIGALRM, pp ); ! 72: } ! 73: ! 74: /* ! 75: * Send a SIGALARM signal in `n' seconds. ! 76: */ ! 77: ualarm(n) ! 78: unsigned n; ! 79: { ! 80: register PROC * pp = SELF; ! 81: register unsigned s; ! 82: ! 83: /* ! 84: * Calculate time left before current alarm timeout. ! 85: */ ! 86: s = 0; ! 87: if ( pp->p_alrmtim.t_last != NULL ) ! 88: s = (pp->p_alrmtim.t_lbolt - lbolt + HZ - 1) / HZ; ! 89: ! 90: /* ! 91: * Cancel previous alarm [if any], start new alarm [if n != 0]. ! 92: */ ! 93: timeout2( &pp->p_alrmtim, (long) n * HZ, sigalrm, pp ); ! 94: ! 95: /* ! 96: * Return time left before previous alarm timeout. ! 97: */ ! 98: return( s ); ! 99: } ! 100: ! 101: /* ! 102: * Send a SIGALARM signal in `n' clock ticks. ! 103: */ ! 104: long ! 105: ualarm2(n) ! 106: long n; ! 107: { ! 108: register PROC * pp = SELF; ! 109: long s; ! 110: ! 111: /* ! 112: * Calculate time left before current alarm timeout. ! 113: */ ! 114: s = 0; ! 115: if ( pp->p_alrmtim.t_last != NULL ) ! 116: s = pp->p_alrmtim.t_lbolt - lbolt; ! 117: ! 118: /* ! 119: * Cancel previous alarm [if any], start new alarm [if n != 0]. ! 120: */ ! 121: timeout2( &pp->p_alrmtim, (long) n, sigalrm, pp ); ! 122: ! 123: /* ! 124: * Return time left before previous alarm timeout. ! 125: */ ! 126: return( s ); ! 127: } ! 128: ! 129: /* ! 130: * Change the size of our data segment. ! 131: */ ! 132: char * ! 133: ubrk(cp) ! 134: char *cp; ! 135: { ! 136: register SEG *sp; ! 137: register vaddr_t sb; ! 138: ! 139: sp = SELF->p_segp[SIPDATA]; ! 140: sb = u.u_segl[SIPDATA].sr_base; ! 141: if (cp != NULL) ! 142: segsize(sp, (vaddr_t)cp-sb); ! 143: #ifdef OLD ! 144: return (0); ! 145: #else ! 146: sb += sp->s_size; ! 147: return ((char *)sb); ! 148: #endif ! 149: } ! 150: ! 151: /* ! 152: * Execute a l.out. ! 153: */ ! 154: uexece(np, argp, envp) ! 155: char *np; ! 156: char *argp[]; ! 157: char *envp[]; ! 158: { ! 159: pexece(np, argp, envp); ! 160: } ! 161: ! 162: /* ! 163: * Exit. ! 164: */ ! 165: uexit(s) ! 166: { ! 167: pexit(s<<8); ! 168: } ! 169: ! 170: /* ! 171: * Fork. ! 172: */ ! 173: ufork() ! 174: { ! 175: return (pfork()); ! 176: } ! 177: ! 178: /* ! 179: * Return date and time. ! 180: */ ! 181: uftime(tbp) ! 182: struct timeb *tbp; ! 183: { ! 184: register int s; ! 185: struct timeb timeb; ! 186: ! 187: timeb.time = timer.t_time; ! 188: /* This should be a machine.h macro to avoid ! 189: * unnecessary long arithmetic and roundoff errors ! 190: */ ! 191: timeb.millitm = timer.t_tick*(1000/HZ); ! 192: timeb.timezone = timer.t_zone; ! 193: timeb.dstflag = timer.t_dstf; ! 194: s = sphi(); ! 195: kucopy(&timeb, tbp, sizeof(timeb)); ! 196: spl(s); ! 197: } ! 198: ! 199: /* ! 200: * Get effective group id. ! 201: */ ! 202: ugetegid() ! 203: { ! 204: return (u.u_gid); ! 205: } ! 206: ! 207: /* ! 208: * Get effective user id. ! 209: */ ! 210: ugeteuid() ! 211: { ! 212: return (u.u_uid); ! 213: } ! 214: ! 215: /* ! 216: * Get group id. ! 217: */ ! 218: ugetgid() ! 219: { ! 220: return (u.u_rgid); ! 221: } ! 222: ! 223: /* ! 224: * Get process id. ! 225: */ ! 226: ugetpid() ! 227: { ! 228: return (SELF->p_pid); ! 229: } ! 230: ! 231: /* ! 232: * Get user id. ! 233: */ ! 234: ugetuid() ! 235: { ! 236: return (u.u_ruid); ! 237: } ! 238: ! 239: /* ! 240: * Get process group. ! 241: */ ! 242: ugetpgrp() ! 243: { ! 244: return (SELF->p_group); ! 245: } ! 246: ! 247: /* ! 248: * Set the process group. ! 249: * When process group is 0 and a terminal is ! 250: * opened, this process is made the base of ! 251: * processes associated with that terminal. ! 252: */ ! 253: usetpgrp() ! 254: { ! 255: register PROC * pp = SELF; ! 256: ! 257: return (pp->p_group = pp->p_pid); ! 258: } ! 259: ! 260: /* ! 261: * Send the signal `sig' to the process with id `pid'. ! 262: */ ! 263: ukill(pid, sig) ! 264: int pid; ! 265: register unsigned sig; ! 266: { ! 267: register PROC *pp; ! 268: register int sigflag; ! 269: ! 270: if ( sig > NSIG ) { ! 271: u.u_error = EINVAL; ! 272: return; ! 273: } ! 274: sigflag = 0; ! 275: lock(pnxgate); ! 276: if (pid > 0) { /* send to matching process */ ! 277: for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) { ! 278: if (pp->p_state == PSDEAD) ! 279: continue; ! 280: if (pp->p_pid == pid) { ! 281: sigflag = 1; ! 282: if ( sig ) { ! 283: if (sigperm(sig, pp)) ! 284: sendsig(sig, pp); ! 285: else ! 286: u.u_error = EPERM; ! 287: } ! 288: break; ! 289: } ! 290: } ! 291: } ! 292: else if (pid < -1) { ! 293: pid = -pid; ! 294: for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) { ! 295: if (pp->p_state == PSDEAD) ! 296: continue; ! 297: if (pp->p_group == pid) { ! 298: sigflag = 1; ! 299: if (sig) { ! 300: if (sigperm(sig, pp)) ! 301: sendsig(sig,pp); ! 302: else ! 303: u.u_error = EPERM; ! 304: } ! 305: } ! 306: } ! 307: } ! 308: else if (pid == 0) { ! 309: for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) { ! 310: if (pp->p_state == PSDEAD) ! 311: continue; ! 312: if (pp->p_group == SELF->p_group) { ! 313: sigflag = 1; ! 314: if (sig && sigperm(sig, pp)) ! 315: sendsig(sig, pp); ! 316: } ! 317: } ! 318: } ! 319: else if (pid == -1) { ! 320: for ( pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw ) { ! 321: if (pp->p_state == PSDEAD) ! 322: continue; ! 323: if (pp->p_pid == 0) ! 324: continue; ! 325: if (pp->p_pid == 1) ! 326: continue; ! 327: if ( pp->p_flags & PFKERN ) ! 328: continue; ! 329: sigflag = 1; ! 330: if (sig && super()) ! 331: sendsig(sig, pp); ! 332: } ! 333: } ! 334: unlock(pnxgate); ! 335: if (sigflag == 0) ! 336: u.u_error = ESRCH; ! 337: return (0); ! 338: } ! 339: ! 340: /* ! 341: * See if we have permission to send the signal, `sig' to the process, `pp'. ! 342: */ ! 343: sigperm(sig, pp) ! 344: register PROC *pp; ! 345: { ! 346: if (u.u_uid == pp->p_uid) ! 347: return (1); ! 348: if (u.u_ruid == pp->p_ruid) { ! 349: if (sig == SIGHUP ! 350: || sig == SIGINT ! 351: || sig == SIGQUIT ! 352: || sig == SIGTERM) ! 353: return (1); ! 354: } ! 355: if (u.u_uid == 0) { ! 356: u.u_flag |= ASU; ! 357: return (1); ! 358: } ! 359: return (0); ! 360: } ! 361: ! 362: /* ! 363: * Lock a process in core. ! 364: */ ! 365: ulock(f) ! 366: { ! 367: if (super() == 0) ! 368: return; ! 369: if (f) ! 370: SELF->p_flags |= PFLOCK; ! 371: else ! 372: SELF->p_flags &= ~PFLOCK; ! 373: return (0); ! 374: } ! 375: ! 376: /* ! 377: * Change priority by the given increment. ! 378: */ ! 379: unice(n) ! 380: register int n; ! 381: { ! 382: n += SELF->p_nice; ! 383: if (n < MINNICE) ! 384: n = MINNICE; ! 385: if (n > MAXNICE) ! 386: n = MAXNICE; ! 387: if (n<SELF->p_nice && super()==0) ! 388: return; ! 389: SELF->p_nice = n; ! 390: return (0); ! 391: } ! 392: ! 393: /* ! 394: * Non existant system call. ! 395: */ ! 396: unone() ! 397: { ! 398: u.u_error = EFAULT; ! 399: } ! 400: ! 401: /* ! 402: * Null system call. ! 403: */ ! 404: unull() ! 405: { ! 406: } ! 407: ! 408: /* ! 409: * Pause. Go to sleep on a channel that nobody will wakeup so that only ! 410: * signals will wake us up. ! 411: */ ! 412: upause() ! 413: { ! 414: for (;;) ! 415: sleep((char *)&u, CVPAUSE, IVPAUSE, SVPAUSE); ! 416: } ! 417: ! 418: /* ! 419: * Start profiling. `bp' is the profile buffer, `n' is the size, `off' ! 420: * is the offset in the users programme and `scale' is the scaling ! 421: * factor. ! 422: */ ! 423: uprofil(bp, n, off, scale) ! 424: register char *bp; ! 425: { ! 426: u.u_pbase = bp; ! 427: u.u_pbend = bp + n; ! 428: u.u_pofft = off; ! 429: u.u_pscale = scale; ! 430: } ! 431: ! 432: /* ! 433: * Process trace. ! 434: */ ! 435: uptrace(req, pid, add, data) ! 436: int *add; ! 437: { ! 438: if (req == 0) { ! 439: SELF->p_flags |= PFTRAC; ! 440: return (0); ! 441: } ! 442: return (ptset(req, pid, add, data)); ! 443: } ! 444: ! 445: /* ! 446: * Set group id. ! 447: */ ! 448: usetgid(gid) ! 449: register int gid; ! 450: { ! 451: if (u.u_gid!=gid && super()==0) ! 452: return; ! 453: u.u_gid = gid; ! 454: u.u_rgid = gid; ! 455: SELF->p_rgid = gid; ! 456: return (0); ! 457: } ! 458: ! 459: /* ! 460: * Set user id. ! 461: */ ! 462: usetuid(uid) ! 463: register int uid; ! 464: { ! 465: if (uid!=u.u_ruid && super()==0) ! 466: return; ! 467: u.u_uid = uid; ! 468: u.u_ruid = uid; ! 469: SELF->p_uid = uid; ! 470: SELF->p_ruid = uid; ! 471: return (0); ! 472: } ! 473: ! 474: /* ! 475: * Set up the action to be taken on a signal. ! 476: */ ! 477: int * ! 478: usignal(sig, f) ! 479: register int sig; ! 480: int (*f)(); ! 481: { ! 482: register PROC *pp; ! 483: register sig_t s; ! 484: register int (*o)(); ! 485: ! 486: pp = SELF; ! 487: if (sig<=0 || sig>NSIG || sig==SIGKILL) { ! 488: u.u_error = EINVAL; ! 489: return; ! 490: } ! 491: s = (sig_t)1 << --sig; ! 492: o = u.u_sfunc[sig]; ! 493: /* This order is critical to isig's use */ ! 494: if (f == SIG_IGN) { ! 495: pp->p_isig |= s; ! 496: u.u_sfunc[sig] = f; ! 497: } else { ! 498: u.u_sfunc[sig] = f; ! 499: pp->p_isig &= ~s; ! 500: } ! 501: pp->p_ssig &= ~s; ! 502: return (o); ! 503: } ! 504: ! 505: /* ! 506: * Load a device driver. ! 507: */ ! 508: usload( np ) ! 509: char *np; ! 510: { ! 511: return( pload( np ) ); ! 512: } ! 513: ! 514: /* ! 515: * Set time and date. ! 516: */ ! 517: ustime(tp) ! 518: register time_t *tp; ! 519: { ! 520: register int s; ! 521: ! 522: if (super() == 0) ! 523: return; ! 524: s = sphi(); ! 525: ukcopy(tp, &timer.t_time, sizeof(*tp)); ! 526: spl(s); ! 527: return (0); ! 528: } ! 529: ! 530: /* ! 531: * Return elapsed ticks since system startup. ! 532: */ ! 533: long ! 534: utick() ! 535: { ! 536: return( lbolt ); ! 537: } ! 538: ! 539: /* ! 540: * Return process times. ! 541: */ ! 542: utimes(tp) ! 543: struct tbuffer *tp; ! 544: { ! 545: register PROC *pp; ! 546: struct tbuffer tbuffer; ! 547: ! 548: pp = SELF; ! 549: tbuffer.tb_utime = pp->p_utime; ! 550: tbuffer.tb_stime = pp->p_stime; ! 551: tbuffer.tb_cutime = pp->p_cutime; ! 552: tbuffer.tb_cstime = pp->p_cstime; ! 553: kucopy(&tbuffer, tp, sizeof(tbuffer)); ! 554: return (0); ! 555: } ! 556: ! 557: /* ! 558: * Unload a device driver. ! 559: */ ! 560: usuload(m) ! 561: register int m; ! 562: { ! 563: if (super() == 0) ! 564: return; ! 565: puload(m); ! 566: return (0); ! 567: } ! 568: ! 569: ! 570: /* ! 571: * Wait for a child to terminate. ! 572: */ ! 573: uwait(stp) ! 574: int *stp; ! 575: { ! 576: register PROC *pp; ! 577: register PROC *ppp; ! 578: register PROC *cpp; ! 579: register int pid; ! 580: ! 581: ppp = SELF; ! 582: for (;;) { ! 583: lock(pnxgate); ! 584: cpp = NULL; ! 585: pp = &procq; ! 586: while ((pp=pp->p_nforw) != &procq) { ! 587: if (pp == ppp) ! 588: continue; ! 589: if (pp->p_ppid != ppp->p_pid) ! 590: continue; ! 591: if ((pp->p_flags&PFSTOP) != 0) ! 592: continue; ! 593: if ((pp->p_flags&PFWAIT) != 0) { ! 594: pp->p_flags &= ~PFWAIT; ! 595: pp->p_flags |= PFSTOP; ! 596: unlock(pnxgate); ! 597: if (stp != NULL) ! 598: putuwd(stp, 0177); ! 599: return (pp->p_pid); ! 600: } ! 601: if (pp->p_state == PSDEAD) { ! 602: ppp->p_cutime += pp->p_utime + pp->p_cutime; ! 603: ppp->p_cstime += pp->p_stime + pp->p_cstime; ! 604: if (stp != NULL) ! 605: putuwd(stp, pp->p_exit); ! 606: pid = pp->p_pid; ! 607: unlock(pnxgate); ! 608: relproc(pp); ! 609: return (pid); ! 610: } ! 611: cpp = pp; ! 612: } ! 613: unlock(pnxgate); ! 614: if (cpp == NULL) { ! 615: u.u_error = ECHILD; ! 616: return; ! 617: } ! 618: sleep((char *)ppp, CVWAIT, IVWAIT, SVWAIT); ! 619: } ! 620: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.