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