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