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