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