Annotation of coherent/d/PS2_KERNEL/coh.386/sys1.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.