|
|
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.