|
|
1.1 ! root 1: /* $Header: /y/coh.386/RCS/sys1.c,v 1.7 92/07/16 16:33:34 hal 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.7 92/07/16 16:33:34 hal ! 21: * Kernel #58 ! 22: * ! 23: * Revision 1.4 92/01/27 12:38:52 hal ! 24: * Forgot to check flag in upgrp(). ! 25: * ! 26: * Revision 1.3 92/01/24 21:29:35 hal ! 27: * Kernel version 29. ! 28: */ ! 29: #include <sys/coherent.h> ! 30: #include <acct.h> ! 31: #include <sys/con.h> ! 32: #include <errno.h> ! 33: #include <sys/proc.h> ! 34: #include <sys/sched.h> ! 35: #include <sys/seg.h> ! 36: #include <sys/stat.h> ! 37: #include <signal.h> ! 38: #include <sys/times.h> ! 39: ! 40: /* ! 41: * Send alarm signal to specified process - function timed by ualarm() ! 42: */ ! 43: sigalrm(pp) ! 44: register PROC * pp; ! 45: { ! 46: sendsig(SIGALRM, pp); ! 47: } ! 48: ! 49: /* ! 50: * Send a SIGALARM signal in `n' seconds. ! 51: */ ! 52: ualarm(n) ! 53: unsigned n; ! 54: { ! 55: register PROC * pp = SELF; ! 56: register unsigned s; ! 57: ! 58: /* ! 59: * Calculate time left before current alarm timeout. ! 60: */ ! 61: s = 0; ! 62: if (pp->p_alrmtim.t_last != NULL) ! 63: s = (pp->p_alrmtim.t_lbolt - lbolt + HZ - 1) / HZ; ! 64: ! 65: /* ! 66: * Cancel previous alarm [if any], start new alarm [if n != 0]. ! 67: */ ! 68: timeout2(&pp->p_alrmtim, (long) n * HZ, sigalrm, pp); ! 69: ! 70: /* ! 71: * Return time left before previous alarm timeout. ! 72: */ ! 73: return(s); ! 74: } ! 75: ! 76: ! 77: /* ! 78: * Change the size of our data segment. ! 79: */ ! 80: char * ! 81: ubrk(cp) ! 82: vaddr_t cp; ! 83: { ! 84: register SEG *sp; ! 85: register vaddr_t sb; ! 86: register SR *stack_sr; ! 87: vaddr_t top_of_stack; ! 88: ! 89: T_HAL(0x8000, printf("%s:ubrk(%x) ", u.u_comm, cp)); ! 90: ! 91: /* ! 92: * Pick up the segment handle for our data segment. ! 93: */ ! 94: sp = SELF->p_segp[SIPDATA]; ! 95: ! 96: /* ! 97: * Extract the starting virtual address for our data segment, ! 98: * as it is currently mapped into the memory space. ! 99: */ ! 100: sb = u.u_segl[SIPDATA].sr_base; ! 101: ! 102: /* ! 103: * We can not move the top of the data segment below the ! 104: * start of the data segment. ! 105: */ ! 106: if (cp < sb) { ! 107: SET_U_ERROR(ENOMEM, ! 108: "Requested brk address is below start of data segment."); ! 109: return 0; ! 110: } ! 111: ! 112: /* ! 113: * Would the request cause a collision with the stack segment? ! 114: * ! 115: * Since the stack grows downward, its top is below its base :-). ! 116: */ ! 117: stack_sr = &u.u_segl[SISTACK]; ! 118: top_of_stack = (stack_sr->sr_base) - (stack_sr->sr_size); ! 119: ! 120: if (btoc(cp) >= btoc(top_of_stack)) { ! 121: SET_U_ERROR(ENOMEM, ! 122: "Requested brk address would collide with stack segment."); ! 123: return 0; ! 124: } ! 125: ! 126: /* ! 127: * Attempt to establish the segment with the newly requested size. ! 128: */ ! 129: segsize(sp, (cp - sb)); ! 130: ! 131: /* ! 132: * Be sure to return the true new top of data segment. ! 133: */ ! 134: sb += sp->s_size; ! 135: ! 136: T_HAL(0x8000, printf("=%x ", sb)); ! 137: return sb; ! 138: } ! 139: ! 140: /* ! 141: * Execute a l.out. ! 142: */ ! 143: uexece(np, argp, envp) ! 144: char *np; ! 145: char *argp[]; ! 146: char *envp[]; ! 147: { ! 148: pexece(np, argp, envp); ! 149: } ! 150: ! 151: /* ! 152: * Exit. ! 153: */ ! 154: uexit(s) ! 155: { ! 156: pexit(s<<8); ! 157: } ! 158: ! 159: /* ! 160: * Fork. ! 161: */ ! 162: ufork() ! 163: { ! 164: return (pfork()); ! 165: } ! 166: ! 167: /* ! 168: * Get group id. ! 169: * Get effective group id. ! 170: */ ! 171: ugetgid() ! 172: { ! 173: u.u_rval2 = u.u_gid; ! 174: return u.u_rgid; ! 175: } ! 176: ! 177: /* ! 178: * Get user id. ! 179: * Get effective user id. ! 180: */ ! 181: ugetuid() ! 182: { ! 183: u.u_rval2 = u.u_uid; ! 184: return u.u_ruid; ! 185: } ! 186: ! 187: /* ! 188: * Get process group. ! 189: * Set the process group. ! 190: * ! 191: * This is System V type setpgrp(). ! 192: * Set process group equal to process id (make process its own group leader). ! 193: * If process was NOT already a group leader, lose its controlling terminal. ! 194: */ ! 195: upgrp(fl) ! 196: { ! 197: register PROC * pp = SELF; ! 198: ! 199: if (fl) { ! 200: if (pp->p_group != pp->p_pid) ! 201: pp->p_ttdev = NODEV; ! 202: pp->p_group = pp->p_pid; ! 203: } ! 204: return pp->p_group; ! 205: } ! 206: ! 207: /* ! 208: * Get process id. ! 209: */ ! 210: ugetpid() ! 211: { ! 212: register PROC *pp = SELF; ! 213: ! 214: u.u_rval2 = pp->p_ppid; ! 215: return pp->p_pid; ! 216: } ! 217: ! 218: /* ! 219: * Send the signal `sig' to the process with id `pid'. ! 220: */ ! 221: ukill(pid, sig) ! 222: int pid; ! 223: register unsigned sig; ! 224: { ! 225: register PROC *pp; ! 226: register int sigflag; ! 227: ! 228: if (sig > NSIG) { ! 229: u.u_error = EINVAL; ! 230: return; ! 231: } ! 232: sigflag = 0; ! 233: lock(pnxgate); ! 234: if (pid > 0) { /* send to matching process */ ! 235: for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) { ! 236: if (pp->p_state == PSDEAD) ! 237: continue; ! 238: if (pp->p_pid == pid) { ! 239: sigflag = 1; ! 240: if (sig) { ! 241: if (sigperm(sig, pp)) ! 242: sendsig(sig, pp); ! 243: else ! 244: u.u_error = EPERM; ! 245: } ! 246: break; ! 247: } ! 248: } ! 249: } ! 250: else if (pid < -1) { ! 251: pid = -pid; ! 252: for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) { ! 253: if (pp->p_state == PSDEAD) ! 254: continue; ! 255: if (pp->p_group == pid) { ! 256: sigflag = 1; ! 257: if (sig) { ! 258: if (sigperm(sig, pp)) ! 259: sendsig(sig,pp); ! 260: else ! 261: u.u_error = EPERM; ! 262: } ! 263: } ! 264: } ! 265: } ! 266: else if (pid == 0) { ! 267: for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) { ! 268: if (pp->p_state == PSDEAD) ! 269: continue; ! 270: if (pp->p_group == SELF->p_group) { ! 271: sigflag = 1; ! 272: if (sig && sigperm(sig, pp)) ! 273: sendsig(sig, pp); ! 274: } ! 275: } ! 276: } ! 277: else if (pid == -1) { ! 278: for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) { ! 279: if (pp->p_state == PSDEAD) ! 280: continue; ! 281: if (pp->p_pid == 0) ! 282: continue; ! 283: if (pp->p_pid == 1) ! 284: continue; ! 285: if (pp->p_flags & PFKERN) ! 286: continue; ! 287: sigflag = 1; ! 288: if (sig && super()) ! 289: sendsig(sig, pp); ! 290: } ! 291: } ! 292: unlock(pnxgate); ! 293: if (sigflag == 0) ! 294: u.u_error = ESRCH; ! 295: return 0; ! 296: } ! 297: ! 298: /* ! 299: * See if we have permission to send the signal, `sig' to the process, `pp'. ! 300: */ ! 301: sigperm(sig, pp) ! 302: register PROC *pp; ! 303: { ! 304: if (u.u_uid == pp->p_uid) ! 305: return (1); ! 306: if (u.u_ruid == pp->p_ruid) { ! 307: if (sig == SIGHUP ! 308: || sig == SIGINT ! 309: || sig == SIGQUIT ! 310: || sig == SIGTERM) ! 311: return (1); ! 312: } ! 313: if (u.u_uid == 0) { ! 314: u.u_flag |= ASU; ! 315: return (1); ! 316: } ! 317: return 0; ! 318: } ! 319: ! 320: /* ! 321: * Lock a process in core. ! 322: */ ! 323: ulock(f) ! 324: { ! 325: if (super() == 0) ! 326: return; ! 327: if (f) ! 328: SELF->p_flags |= PFLOCK; ! 329: else ! 330: SELF->p_flags &= ~PFLOCK; ! 331: return 0; ! 332: } ! 333: ! 334: /* ! 335: * Change priority by the given increment. ! 336: */ ! 337: unice(n) ! 338: register int n; ! 339: { ! 340: n += SELF->p_nice; ! 341: if (n < MINNICE) ! 342: n = MINNICE; ! 343: if (n > MAXNICE) ! 344: n = MAXNICE; ! 345: if (n<SELF->p_nice && super()==0) ! 346: return; ! 347: SELF->p_nice = n; ! 348: return 0; ! 349: } ! 350: ! 351: /* ! 352: * Non existant system call. ! 353: */ ! 354: unone() ! 355: { ! 356: u.u_error = EFAULT; ! 357: } ! 358: ! 359: /* ! 360: * Null system call. ! 361: */ ! 362: unull() ! 363: { ! 364: } ! 365: ! 366: /* ! 367: * Pause. Go to sleep on a channel that nobody will wakeup so that only ! 368: * signals will wake us up. ! 369: */ ! 370: upause() ! 371: { ! 372: for (;;) ! 373: v_sleep((char *)&u, CVPAUSE, IVPAUSE, SVPAUSE, "pause"); ! 374: /* The pause system call. */ ! 375: } ! 376: ! 377: /* ! 378: * Start/stop profiling. ! 379: * ! 380: * buff: address in user data of an array of shorts ! 381: * bufsiz: number of bytes in the area at buff ! 382: * offset: address in user text of start of profiling area ! 383: * scale: 0 or 1 - turn off profiling ! 384: * other - treat as 16 bit scale factor ! 385: * ! 386: * For purposes of compatibility with System 5, scale values work as follows: ! 387: * 0xFFFF profile buffer is same length as text being profiled. ! 388: * 0x7FFF profile buffer is half as long as text being profiled. ! 389: * 0x4000 profile buffer is one fourth as long as text profiled. ! 390: * (each short in the buffer covers 8 bytes of text) ! 391: * ... ... ! 392: * 0x0002 each short in the buffer covers 64K bytes of text. ! 393: * ! 394: * Values 0xFFFF and 0x7FFF are used, for historical reasons, when 0x10000 ! 395: * and 0x8000, respectively, should be used. To clean up the ensuing ! 396: * arithmetic, there is an upward rounding kluge below. ! 397: * ! 398: * Each clock interrupt, take (pc - offset) * scale * (2**-16) as a byte ! 399: * offset into pbase. Add 1 to the short at or below the given address ! 400: * when profiling. ! 401: */ ! 402: uprofil(buff, bufsiz, offset, scale) ! 403: short * buff; ! 404: int bufsiz, offset, scale; ! 405: { ! 406: u.u_pbase = buff; ! 407: u.u_pbend = buff + bufsiz; ! 408: u.u_pofft = offset; ! 409: u.u_pscale = scale & 0xffff; /* scale is really unsigned short */ ! 410: ! 411: /* round up kluge - see above */ ! 412: if ((scale & 0xfff) == 0xfff) ! 413: u.u_pscale++; ! 414: } ! 415: ! 416: /* ! 417: * Process trace. ! 418: */ ! 419: uptrace(req, pid, add, data) ! 420: int *add; ! 421: { ! 422: if (req == 0) { ! 423: SELF->p_flags |= PFTRAC; ! 424: return 0; ! 425: } ! 426: return (ptset(req, pid, add, data)); ! 427: } ! 428: ! 429: /* ! 430: * Set group id. ! 431: */ ! 432: usetgid(gid) ! 433: register int gid; ! 434: { ! 435: if (u.u_gid!=gid && super()==0) ! 436: return; ! 437: u.u_gid = gid; ! 438: u.u_rgid = gid; ! 439: SELF->p_rgid = gid; ! 440: return 0; ! 441: } ! 442: ! 443: /* ! 444: * Set user id. ! 445: */ ! 446: usetuid(uid) ! 447: register int uid; ! 448: { ! 449: if (uid!=u.u_ruid && super()==0) ! 450: return; ! 451: u.u_uid = uid; ! 452: u.u_ruid = uid; ! 453: SELF->p_uid = uid; ! 454: SELF->p_ruid = uid; ! 455: return 0; ! 456: } ! 457: ! 458: /* ! 459: * Load a device driver. ! 460: */ ! 461: usload(np) ! 462: char *np; ! 463: { ! 464: return pload(np); ! 465: } ! 466: ! 467: /* ! 468: * Set time and date. ! 469: */ ! 470: ustime(tp) ! 471: register time_t *tp; ! 472: { ! 473: register int s; ! 474: ! 475: if (super() == 0) ! 476: return; ! 477: s = sphi(); ! 478: ukcopy(tp, &timer.t_time, sizeof(*tp)); ! 479: spl(s); ! 480: return 0; ! 481: } ! 482: ! 483: /* ! 484: * Return process times. ! 485: */ ! 486: utimes(tp) ! 487: struct tms *tp; ! 488: { ! 489: register PROC *pp; ! 490: struct tms tbuffer; ! 491: ! 492: pp = SELF; ! 493: tbuffer.tms_utime = pp->p_utime; ! 494: tbuffer.tms_stime = pp->p_stime; ! 495: tbuffer.tms_cutime = pp->p_cutime; ! 496: tbuffer.tms_cstime = pp->p_cstime; ! 497: kucopy(&tbuffer, tp, sizeof(tbuffer)); ! 498: return 0; ! 499: } ! 500: ! 501: /* ! 502: * Unload a device driver. ! 503: */ ! 504: usuload(m) ! 505: register int m; ! 506: { ! 507: if (super() == 0) ! 508: return; ! 509: puload(m); ! 510: return 0; ! 511: } ! 512: ! 513: ! 514: /* ! 515: * Wait for a child to terminate. ! 516: */ ! 517: uwait() ! 518: { ! 519: register PROC *pp; ! 520: register PROC *ppp; ! 521: register PROC *cpp; ! 522: register int pid; ! 523: ! 524: ppp = SELF; ! 525: for (;;) { ! 526: lock(pnxgate); ! 527: cpp = NULL; ! 528: pp = &procq; ! 529: while ((pp=pp->p_nforw) != &procq) { ! 530: if (pp == ppp) ! 531: continue; ! 532: if (pp->p_ppid != ppp->p_pid) ! 533: continue; ! 534: if ((pp->p_flags&PFSTOP) != 0) ! 535: continue; ! 536: if ((pp->p_flags&PFWAIT) != 0) { ! 537: pp->p_flags &= ~PFWAIT; ! 538: pp->p_flags |= PFSTOP; ! 539: unlock(pnxgate); ! 540: u.u_rval2 = 0177; ! 541: T_PIGGY(0x100, ! 542: printf("<uwait(WAIT): pid: %d ppid: %d rval2: 0x%x, signo: %d>", ! 543: pp->p_pid, pp->p_ppid, u.u_rval2, u.u_signo); ! 544: ); ! 545: return (pp->p_pid); ! 546: } ! 547: if (pp->p_state == PSDEAD) { ! 548: ppp->p_cutime += pp->p_utime + pp->p_cutime; ! 549: ppp->p_cstime += pp->p_stime + pp->p_cstime; ! 550: u.u_rval2 = pp->p_exit; ! 551: pid = pp->p_pid; ! 552: unlock(pnxgate); ! 553: relproc(pp); ! 554: T_PIGGY(0x100, ! 555: printf("<uwait(DEAD): pid: %d ppid: %d rval2: 0x%x, signo: %d>", ! 556: pp->p_pid, pp->p_ppid, u.u_rval2, u.u_signo); ! 557: ); ! 558: return (pid); ! 559: } ! 560: cpp = pp; ! 561: } ! 562: unlock(pnxgate); ! 563: if (cpp == NULL) { ! 564: u.u_error = ECHILD; ! 565: #if 0 /* This error happens so often it tends to run away. */ ! 566: SET_U_ERROR( ECHILD, ! 567: "there are no children to wait for" ); ! 568: #endif /* 0 */ ! 569: T_PIGGY( 0x100, printf(";"); ); ! 570: return; ! 571: } ! 572: v_sleep((char *)ppp, CVWAIT, IVWAIT, SVWAIT, "wait"); ! 573: /* Wait for a child to terminate. */ ! 574: } ! 575: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.