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