Annotation of coherent/b/kernel/coh.386/sys1.c, revision 1.1.1.1

1.1       root        1: /* (lgl-
                      2:  *     The information contained herein is a trade secret of Mark Williams
                      3:  *     Company, and  is confidential information.  It is provided  under a
                      4:  *     license agreement,  and may be  copied or disclosed  only under the
                      5:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      6:  *     material without the express written authorization of Mark Williams
                      7:  *     Company or persuant to the license agreement is unlawful.
                      8:  *
                      9:  *     COHERENT Version 2.3.37
                     10:  *     Copyright (c) 1982, 1983, 1984.
                     11:  *     An unpublished work by Mark Williams Company, Chicago.
                     12:  *     All rights reserved.
                     13:  -lgl) */
                     14: /*
                     15:  * coh.386/sys1.c
                     16:  *
                     17:  * Coherent.
                     18:  * General system calls.
                     19:  *
                     20:  * Revised: Tue May 11 11:12:03 1993 CDT
                     21:  */
                     22: #include <sys/coherent.h>
                     23: #include <sys/acct.h>
                     24: #include <sys/con.h>
                     25: #include <sys/wait.h>
                     26: #include <errno.h>
                     27: #include <sys/proc.h>
                     28: #include <sys/sched.h>
                     29: #include <sys/seg.h>
                     30: #include <sys/stat.h>
                     31: #include <signal.h>
                     32: #include <sys/times.h>
                     33: 
                     34: /*
                     35:  * Send alarm signal to specified process - function timed by ualarm()
                     36:  */
                     37: sigalrm(pp)
                     38: register PROC * pp;
                     39: {
                     40:        sendsig(SIGALRM, pp);
                     41: }
                     42: 
                     43: /*
                     44:  * Send a SIGALARM signal in `n' seconds.
                     45:  */
                     46: ualarm(n)
                     47: unsigned n;
                     48: {
                     49:        register PROC * pp = SELF;
                     50:        register unsigned s;
                     51: 
                     52:        /*
                     53:         * Calculate time left before current alarm timeout.
                     54:         */
                     55:        s = 0;
                     56:        if (pp->p_alrmtim.t_last != NULL)
                     57:                s = (pp->p_alrmtim.t_lbolt - lbolt + HZ - 1) / HZ;
                     58: 
                     59:        /*
                     60:         * Cancel previous alarm [if any], start new alarm [if n != 0].
                     61:         */
                     62:        timeout2(&pp->p_alrmtim, (long) n * HZ, sigalrm, pp);
                     63: 
                     64:        /*
                     65:         * Return time left before previous alarm timeout.
                     66:         */
                     67:        return(s);
                     68: }
                     69: 
                     70: 
                     71: /*
                     72:  * Change the size of our data segment.
                     73:  */
                     74: char *
                     75: ubrk(cp)
                     76: caddr_t cp;
                     77: {
                     78:        register SEG *sp;
                     79:        register caddr_t sb;
                     80:        register SR     *stack_sr;
                     81:        caddr_t top_of_stack;
                     82: 
                     83:        T_HAL(0x8000, printf("%s:ubrk(%x) ", u.u_comm, cp));
                     84: 
                     85:        /*
                     86:         * Pick up the segment handle for our data segment.
                     87:         */
                     88:        sp = SELF->p_segp[SIPDATA];
                     89: 
                     90:        /*
                     91:         * Extract the starting virtual address for our data segment,
                     92:         * as it is currently mapped into the memory space.
                     93:         */
                     94:        sb = u.u_segl[SIPDATA].sr_base;
                     95: 
                     96:        /*
                     97:         * We can not move the top of the data segment below the
                     98:         * start of the data segment.
                     99:         */
                    100:        if (cp < sb) {
                    101:                SET_U_ERROR(ENOMEM,
                    102:                    "Requested brk address is below start of data segment.");
                    103:                return 0;
                    104:        }
                    105: 
                    106:        /*
                    107:         * Would the request cause a collision with the stack segment?
                    108:         *
                    109:         * Since the stack grows downward, its top is below its base :-).
                    110:         */
                    111:        stack_sr = &u.u_segl[SISTACK];
                    112:        top_of_stack = (stack_sr->sr_base) - (stack_sr->sr_size);
                    113: 
                    114:        if (btoc(cp) >= btoc(top_of_stack)) {
                    115:                SET_U_ERROR(ENOMEM,
                    116:                    "Requested brk address would collide with stack segment.");
                    117:                return 0;
                    118:        }
                    119: 
                    120:        /*
                    121:         * Attempt to establish the segment with the newly requested size.
                    122:         */
                    123:        segsize(sp, (cp - sb));
                    124: 
                    125:        /*
                    126:         * Be sure to return the true new top of data segment.
                    127:         */
                    128:        sb += sp->s_size;
                    129: 
                    130:        T_HAL(0x8000, printf("=%x ", sb));
                    131:        return sb;
                    132: }
                    133: 
                    134: /*
                    135:  * Execute a l.out.
                    136:  */
                    137: uexece(np, argp, envp)
                    138: char *np;
                    139: char *argp[];
                    140: char *envp[];
                    141: {
                    142:        pexece(np, argp, envp);
                    143: }
                    144: 
                    145: /*
                    146:  * Exit.
                    147:  */
                    148: uexit(s)
                    149: {
                    150:        pexit(s<<8);
                    151: }
                    152: 
                    153: /*
                    154:  * Fork.
                    155:  */
                    156: ufork()
                    157: {
                    158:        return (pfork());
                    159: }
                    160: 
                    161: /*
                    162:  * Get group id.
                    163:  * Get effective group id.
                    164:  */
                    165: ugetgid()
                    166: {
                    167:        u.u_rval2 = u.u_gid;
                    168:        return u.u_rgid;
                    169: }
                    170: 
                    171: /*
                    172:  * Get user id.
                    173:  * Get effective user id.
                    174:  */
                    175: ugetuid()
                    176: {
                    177:        u.u_rval2 = u.u_uid;
                    178:        return u.u_ruid;
                    179: }
                    180: 
                    181: /*
                    182:  * Get process group.
                    183:  * Set the process group.
                    184:  *
                    185:  * This is System V type setpgrp().
                    186:  * Set process group equal to process id (make process its own group leader).
                    187:  * If process was NOT already a group leader, lose its controlling terminal.
                    188:  */
                    189: upgrp(fl)
                    190: {
                    191:        register PROC * pp = SELF;
                    192:        
                    193:        if (fl) {
                    194:                if (pp->p_group != pp->p_pid)
                    195:                        pp->p_ttdev = NODEV;
                    196:                pp->p_group = pp->p_pid;
                    197:        }
                    198:        return pp->p_group;
                    199: }
                    200: 
                    201: /*
                    202:  * Get process id.
                    203:  */
                    204: ugetpid()
                    205: {
                    206:        register PROC *pp = SELF;
                    207: 
                    208:        u.u_rval2 = pp->p_ppid;
                    209:        return pp->p_pid;
                    210: }
                    211: 
                    212: /*
                    213:  * Send the signal `sig' to the process with id `pid'.
                    214:  */
                    215: ukill(pid, sig)
                    216: int pid;
                    217: register unsigned sig;
                    218: {
                    219:        register PROC *pp;
                    220:        register int sigflag;
                    221: 
                    222:        if (sig > NSIG) {
                    223:                u.u_error = EINVAL;
                    224:                return;
                    225:        }
                    226:        sigflag = 0;
                    227:        lock(pnxgate);
                    228:        if (pid > 0) {  /* send to matching process */
                    229:                for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) {
                    230:                        if (pp->p_state == PSDEAD)
                    231:                                continue;
                    232:                        if (pp->p_pid == pid) {
                    233:                                sigflag = 1;
                    234:                                if (sig) {
                    235:                                        if (sigperm(sig, pp))
                    236:                                                sendsig(sig, pp);
                    237:                                        else
                    238:                                                u.u_error = EPERM;
                    239:                                }
                    240:                                break;
                    241:                        }
                    242:                }
                    243:        }
                    244:        else if (pid < -1) {
                    245:                pid = -pid;
                    246:                for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) {
                    247:                        if (pp->p_state == PSDEAD)
                    248:                                continue;
                    249:                        if (pp->p_group == pid) {
                    250:                                sigflag = 1;
                    251:                                if (sig) {
                    252:                                        if (sigperm(sig, pp))
                    253:                                                sendsig(sig,pp);
                    254:                                        else
                    255:                                                u.u_error = EPERM;
                    256:                                }
                    257:                        }
                    258:                }
                    259:        }
                    260:        else if (pid == 0) {
                    261:                for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) {
                    262:                        if (pp->p_state == PSDEAD)
                    263:                                continue;
                    264:                        if (pp->p_group == SELF->p_group) {
                    265:                                sigflag = 1;
                    266:                                if (sig && sigperm(sig, pp))
                    267:                                        sendsig(sig, pp);
                    268:                        }
                    269:                }
                    270:        }
                    271:        else if (pid == -1) {
                    272:                for (pp=procq.p_nforw; pp != &procq; pp=pp->p_nforw) {
                    273:                        if (pp->p_state == PSDEAD)
                    274:                                continue;
                    275:                        if (pp->p_pid == 0)
                    276:                                continue;
                    277:                        if (pp->p_pid == 1)
                    278:                                continue;
                    279:                        if (pp->p_flags & PFKERN)
                    280:                                continue;
                    281:                        sigflag = 1;
                    282:                        if (sig && super())
                    283:                                sendsig(sig, pp);
                    284:                }
                    285:        }
                    286:        unlock(pnxgate);
                    287:        if (sigflag == 0)
                    288:                u.u_error = ESRCH;
                    289:        return 0;
                    290: }
                    291: 
                    292: /*
                    293:  * See if we have permission to send the signal, `sig' to the process, `pp'.
                    294:  */
                    295: sigperm(sig, pp)
                    296: register PROC *pp;
                    297: {
                    298:        if (u.u_uid == pp->p_uid)
                    299:                return (1);
                    300:        if (u.u_ruid == pp->p_ruid) {
                    301:                if (sig == SIGHUP
                    302:                ||  sig == SIGINT
                    303:                ||  sig == SIGQUIT
                    304:                ||  sig == SIGTERM)
                    305:                        return (1);
                    306:        }
                    307:        if (u.u_uid == 0) {
                    308:                u.u_flag |= ASU;
                    309:                return (1);
                    310:        }
                    311:        return 0;
                    312: }
                    313: 
                    314: /*
                    315:  * Lock a process in core.
                    316:  */
                    317: ulock(f)
                    318: {
                    319:        if (super() == 0)
                    320:                return;
                    321:        if (f)
                    322:                SELF->p_flags |= PFLOCK;
                    323:        else
                    324:                SELF->p_flags &= ~PFLOCK;
                    325:        return 0;
                    326: }
                    327: 
                    328: /*
                    329:  * Change priority by the given increment.
                    330:  */
                    331: unice(n)
                    332: register int n;
                    333: {
                    334:        n += SELF->p_nice;
                    335:        if (n < MINNICE)
                    336:                n = MINNICE;
                    337:        if (n > MAXNICE)
                    338:                n = MAXNICE;
                    339:        if (n<SELF->p_nice && super()==0)
                    340:                return;
                    341:        SELF->p_nice = n;
                    342:        return 0;
                    343: }
                    344: 
                    345: /*
                    346:  * Non existant system call.
                    347:  */
                    348: unone()
                    349: {
                    350:        u.u_error = EFAULT;
                    351: }
                    352: 
                    353: /*
                    354:  * Null system call.
                    355:  */
                    356: unull()
                    357: {
                    358: }
                    359: 
                    360: /*
                    361:  * Pause.  Go to sleep on a channel that nobody will wakeup so that only
                    362:  * signals will wake us up.
                    363:  */
                    364: upause()
                    365: {
                    366:        x_sleep((char *)&u, prilo, slpriSigLjmp, "pause");
                    367: }
                    368: 
                    369: /*
                    370:  * Start/stop profiling.
                    371:  *
                    372:  * buff:       address in user data of an array of shorts
                    373:  * bufsiz:     number of bytes in the area at buff
                    374:  * offset:     address in user text of start of profiling area
                    375:  * scale:      0 or 1 - turn off profiling
                    376:  *             other - treat as 16 bit scale factor
                    377:  *
                    378:  * For purposes of compatibility with System 5, scale values work as follows:
                    379:  *     0xFFFF  profile buffer is same length as text being profiled.
                    380:  *     0x7FFF  profile buffer is half as long as text being profiled.
                    381:  *     0x4000  profile buffer is one fourth as long as text profiled.
                    382:  *             (each short in the buffer covers 8 bytes of text)
                    383:  *     ...     ...
                    384:  *     0x0002  each short in the buffer covers 64K bytes of text.
                    385:  *
                    386:  * Values 0xFFFF and 0x7FFF are used, for historical reasons, when 0x10000
                    387:  * and 0x8000, respectively, should be used.  To clean up the ensuing
                    388:  * arithmetic, there is an upward rounding kluge below.
                    389:  *
                    390:  * Each clock interrupt, take (pc - offset) * scale * (2**-16) as a byte
                    391:  * offset into pbase.  Add 1 to the short at or below the given address
                    392:  * when profiling.
                    393:  */
                    394: uprofil(buff, bufsiz, offset, scale)
                    395: short * buff;
                    396: int bufsiz, offset, scale;
                    397: {
                    398:        u.u_pbase = buff;
                    399:        u.u_pbend = buff + bufsiz;
                    400:        u.u_pofft = offset;
                    401:        u.u_pscale = scale & 0xffff;    /* scale is really unsigned short */
                    402: 
                    403:        /* round up kluge - see above */
                    404:        if ((scale & 0xfff) == 0xfff)
                    405:                u.u_pscale++;
                    406: }
                    407: 
                    408: /*
                    409:  * Process trace.
                    410:  */
                    411: uptrace(req, pid, add, data)
                    412: int *add;
                    413: {
                    414:        int ret;
                    415: 
                    416: #ifdef TRACER
                    417:        int readChild = 0;      /* for debug, true if reading child memory */
                    418: 
                    419:        if (t_hal & 0x10000) {
                    420:                switch(req) {
                    421:                case 0: /* init called by child */
                    422:                        printf("PSetup: child=%d  ", SELF->p_pid);
                    423:                        break;
                    424:                case 1: /* parent reads child text */
                    425:                        printf("PRdT: add=%x ", add);
                    426:                        readChild = 1;
                    427:                        break;
                    428:                case 2: /* parent reads child data */
                    429:                        printf("PRdD: add=%x ", add);
                    430:                        readChild = 1;
                    431:                        break;
                    432:                case 3: /* parent reads child u area */
                    433:                        printf("PRdU: add=%x ", add);
                    434:                        readChild = 1;
                    435:                        break;
                    436:                case 4: /* parent writes child text */
                    437:                        printf("PWrT: add=%x data=%x  ", add, data);
                    438:                        break;
                    439:                case 5: /* parent writes child data */
                    440:                        printf("PWrD: add=%x data=%x  ", add, data);
                    441:                        break;
                    442:                case 6: /* parent writes child u area */
                    443:                        printf("PWrU: add=%x data=%x ", add, data);
                    444:                        break;
                    445:                case 7: /* resume child, maybe fake signal to child */
                    446:                        printf("PResume: sig=%d  ", data);
                    447:                        break;
                    448:                case 8: /* terminate child */
                    449:                        printf("PTerm: pid=%d  ", pid);
                    450:                        break;
                    451:                case 9: /* single-step child, maybe fake signal to child */
                    452:                        printf("PSStp: sig=%d  ", data);
                    453:                        break;
                    454:                }
                    455:        }
                    456: #endif
                    457: 
                    458:        if (req == 0) {
                    459:                SELF->p_flags |= PFTRAC;
                    460:                ret = 0;
                    461:        } else
                    462:                ret = ptset(req, pid, add, data);
                    463: 
                    464: #ifdef TRACER
                    465:        if (t_hal & 0x10000) {
                    466:                if (readChild)
                    467:                        printf("data=%x  ", ret);
                    468:        }
                    469: #endif
                    470: 
                    471:        return ret;
                    472: }
                    473: 
                    474: /*
                    475:  * Set group id.
                    476:  *
                    477:  * As in SVID issue 2:
                    478:  *
                    479:  * if effective gid is superuser
                    480:  *     set real, effective, and saved effective gid to argument "gid"
                    481:  * else if real gid is same as "gid"
                    482:  *     set effective gid to "gid"
                    483:  * else if saved effective gid is same as "gid"
                    484:  *     set effective gid to "gid"
                    485:  */
                    486: usetgid(gid)
                    487: register int gid;
                    488: {
                    489:        if (super()) {
                    490:                u.u_gid = u.u_rgid = u.u_egid = gid;
                    491:                SELF->p_rgid = gid;
                    492:        } else {
                    493:                u.u_error = 0;  /* super() sets u_error when it fails */
                    494:                if (u.u_rgid == gid || u.u_egid == gid) {
                    495:                        u.u_gid = gid;
                    496:                } else {
                    497:                        SET_U_ERROR(EPERM, "Illegal gid");
                    498:                }
                    499:        }
                    500:        return 0;
                    501: }
                    502: 
                    503: /*
                    504:  * Set user id.
                    505:  *
                    506:  * As in SVID issue 2:
                    507:  *
                    508:  * if effective uid is superuser
                    509:  *     set real, effective, and saved effective uid to argument "uid"
                    510:  * else if real uid is same as "uid"
                    511:  *     set effective uid to "uid"
                    512:  * else if saved effective uid is same as "uid"
                    513:  *     set effective uid to "uid"
                    514:  */
                    515: usetuid(uid)
                    516: register int uid;
                    517: {
                    518:        if (super()) {
                    519:                u.u_uid = u.u_ruid = u.u_euid = uid;
                    520:                SELF->p_uid = SELF->p_ruid = uid;
                    521:        } else {
                    522:                u.u_error = 0;  /* super() sets u_error when it fails */
                    523:                if (u.u_ruid == uid || u.u_euid == uid) {
                    524:                        SELF->p_uid = u.u_uid = uid;
                    525:                } else {
                    526:                        SET_U_ERROR(EPERM, "Illegal uid");
                    527:                }
                    528:        }
                    529:        return 0;
                    530: }
                    531: 
                    532: /*
                    533:  * Load a device driver.
                    534:  */
                    535: usload(np)
                    536: char *np;
                    537: {
                    538:        return pload(np);
                    539: }
                    540: 
                    541: /*
                    542:  * Set time and date.
                    543:  *
                    544:  * Unlike the libc interface, this routine expects a time_t value
                    545:  * as an arg, not a time_t pointer.
                    546:  */
                    547: ustime(tp)
                    548: time_t tp;
                    549: {
                    550:        register int s;
                    551: 
                    552:        if (super() == 0) {
                    553:                return;
                    554:        }
                    555:        s = sphi();
                    556:        ukcopy(&tp, &timer.t_time, sizeof(tp));
                    557:        spl(s);
                    558:        return 0;
                    559: }
                    560: 
                    561: /*
                    562:  * Return process times.
                    563:  */
                    564: utimes(tp)
                    565: struct tms *tp;
                    566: {
                    567:        register PROC *pp;
                    568:        struct tms tbuffer;
                    569: 
                    570:        if (tp) {
                    571:                pp = SELF;
                    572:                tbuffer.tms_utime = pp->p_utime;
                    573:                tbuffer.tms_stime = pp->p_stime;
                    574:                tbuffer.tms_cutime = pp->p_cutime;
                    575:                tbuffer.tms_cstime = pp->p_cstime;
                    576:                kucopyS(&tbuffer, tp, sizeof(tbuffer));
                    577:        }
                    578:        return lbolt;
                    579: }
                    580: 
                    581: /*
                    582:  * Unload a device driver.
                    583:  */
                    584: usuload(m)
                    585: register int m;
                    586: {
                    587:        if (super() == 0)
                    588:                return;
                    589:        puload(m);
                    590:        return 0;
                    591: }
                    592: 
                    593: /*
                    594:  * Wait for a child to terminate.
                    595:  *
                    596:  * iBCS2 says the same system call number is wait() and waitpid(), the
                    597:  * distinction being in how the psw is set on entry.
                    598:  *
                    599:  * iBCS2 fails to mention that when wait() or waitpid() report status
                    600:  * by writing into the pointer supplied, the status is put into %edx by
                    601:  * the kernel, and moved from there into user space by the function in
                    602:  * libc.a.  uwait() and uwaitpid() specify a value for %edx by writing
                    603:  * to u.u_rval2.
                    604:  *
                    605:  * Do wait() unless (ZF|PF|SF|OF) (=WPMASK) are set in psw.
                    606:  */
                    607: #define        WPMASK  0x8C4
                    608: 
                    609: uwait(arg1, arg2, arg3)
                    610: {
                    611:        register PROC *pp;
                    612:        register PROC *ppp;
                    613:        register PROC *cpp;
                    614:        register int pid;
                    615: 
                    616:        if ((u.u_regl[EFL] & WPMASK) == WPMASK)
                    617:                return uwaitpid(arg1, arg2, arg3);
                    618: 
                    619:        /* Wait for a child to stop or die. */
                    620:        T_HAL(8, printf("[%d]waits ", SELF->p_pid));
                    621:        ppp = SELF;
                    622:        for (;;) {
                    623:                int x_s;
                    624: 
                    625:                /* Look at all processes. */
                    626:                lock(pnxgate);
                    627:                cpp = NULL;
                    628:                pp = &procq;
                    629:                while ((pp=pp->p_nforw) != &procq) {
                    630: 
                    631:                        /* Ignore the current process. */
                    632:                        if (pp == ppp)
                    633:                                continue;
                    634:                        /*
                    635:                         * Ignore processes that aren't children of the
                    636:                         * current one.
                    637:                         */
                    638:                        if (pp->p_ppid != ppp->p_pid)
                    639:                                continue;
                    640:                        if (pp->p_flags&PFSTOP)
                    641:                                continue;
                    642: 
                    643:                        /* Here is a child that hit a breakpoint. */
                    644:                        if (pp->p_flags&PFWAIT) {
                    645:                                int work;       /* virtual click number */
                    646:                                int childUseg;  /* system global addr */
                    647:                                UPROC * uprc;
                    648:                                SEG * sp;
                    649: 
                    650:                                pp->p_flags &= ~PFWAIT;
                    651:                                pp->p_flags |= PFSTOP;
                    652: 
                    653:                                /* fetch u.u_signo from the child */
                    654: 
                    655:                                /* Find u area for child process pp */
                    656:                                sp = pp->p_segp[SIUSERP];
                    657:                                childUseg = MAPIO(sp->s_vmem, U_OFFSET);
                    658:                                work = workAlloc();
                    659:                                ptable1_v[work] =
                    660:                                  sysmem.u.pbase[btocrd(childUseg)] | SEG_RW;
                    661:                                mmuupd();
                    662:                                uprc = (UPROC *) (ctob(work) + U_OFFSET);
                    663:                                u.u_rval2 = ((uprc->u_signo)<<8) | 0177;
                    664:                                workFree(work);
                    665: 
                    666:                                unlock(pnxgate);
                    667:                                T_HAL(8, printf("[%d]ends waiting, %d stopped ",
                    668:                                  SELF->p_pid, pid));
                    669:                                return pp->p_pid;
                    670:                        }
                    671:                        if (pp->p_state == PSDEAD) {
                    672:                                ppp->p_cutime += pp->p_utime + pp->p_cutime;
                    673:                                ppp->p_cstime += pp->p_stime + pp->p_cstime;
                    674:                                u.u_rval2 = pp->p_exit;
                    675:                                pid = pp->p_pid;
                    676:                                unlock(pnxgate);
                    677:                                relproc(pp);
                    678:                                if (SIG_BIT(SIGCLD) & ppp->p_isig)
                    679:                                        continue;
                    680:                                else {
                    681:                                        T_HAL(8, printf("[%d]ends waiting,"
                    682:                                          " %d died ", SELF->p_pid, pid));
                    683:                                        return pid;
                    684:                                }
                    685:                        }
                    686:                        cpp = pp;
                    687:                }
                    688:                unlock(pnxgate);
                    689:                if (cpp == NULL) {
                    690:                        T_HAL(8, printf("[%d]ends waiting, no children ",
                    691:                          SELF->p_pid));
                    692:                        u.u_error = ECHILD;
                    693:                        return;
                    694:                }
                    695:                x_s = x_sleep((char *)ppp, prilo, slpriSigLjmp, "wait");
                    696:                /* Wait for a child to terminate.  */
                    697:        }
                    698: }
                    699: 
                    700: /*
                    701:  * waitpid() and wait() share the same system call number under BCS.
                    702:  *
                    703:  * pid argument:
                    704:  *     >  0    wait for child whose process matches pid
                    705:  *     =  0    wait for any child in current process group
                    706:  *     = -1    wait for any child - same as wait()
                    707:  *     < -1    wait for any child in group given by -pid
                    708:  *
                    709:  * The only waitpid() options supported are WNOHANG and WUNTRACED.
                    710:  *
                    711:  */
                    712: int
                    713: uwaitpid(opid, stat_loc, options)
                    714: register pid_t opid;
                    715: int    *stat_loc, options;
                    716: {
                    717:        register PROC *pp;
                    718:        register PROC *ppp;
                    719:        register PROC *cpp;
                    720:        register int pid;
                    721: 
                    722:        if (options & WUNTRACED) {      
                    723:                 printf("waitpid(%d,%d, WUNTRACED): unsupported\n", opid,
                    724:                                                                     stat_loc);
                    725:                u.u_error = EINVAL;
                    726:                return;
                    727:        }
                    728: 
                    729:        /* Wait for a child to stop or die. */
                    730:        ppp = SELF;
                    731:        for (;;) {
                    732:                int x_s;
                    733: 
                    734:                /* Look at all processes. */
                    735:                lock(pnxgate);
                    736:                cpp = NULL;
                    737:                pp = &procq;
                    738:                while ((pp=pp->p_nforw) != &procq) {
                    739: 
                    740:                        /* Ignore the current process. */
                    741:                        if (pp == ppp)
                    742:                                continue;
                    743:                        /*
                    744:                         * Ignore processes that aren't children of the
                    745:                         * current one.
                    746:                         */
                    747:                        if (pp->p_ppid != ppp->p_pid)
                    748:                                continue;
                    749: 
                    750:                        if (pp->p_flags&PFSTOP)
                    751:                                continue;
                    752: 
                    753:                        /* If opid == 0 we want to match gids */
                    754:                        if ((opid == 0) && (pp->p_group != ppp->p_group))
                    755:                                continue;
                    756: 
                    757:                        /* If opid>0, want to match opid to child pid */
                    758:                        else if ((opid > 0) && (opid != pp->p_pid))
                    759:                                continue;
                    760: 
                    761:                        /* If opid<-1, want to match -opid to child gid */
                    762:                        else if ((opid < -1) && ((-opid) != pp->p_group))
                    763:                                continue;
                    764: 
                    765:                        /* if opid == -1, then any child is acceptable */
                    766: 
                    767:                        /* Here is an acceptable child that hit a breakpoint. */
                    768:                        if (pp->p_flags&PFWAIT) {
                    769:                                int work;       /* virtual click number */
                    770:                                int childUseg;  /* system global addr */
                    771:                                UPROC * uprc;
                    772:                                SEG * sp;
                    773: 
                    774:                                pp->p_flags &= ~PFWAIT;
                    775:                                pp->p_flags |= PFSTOP;
                    776: 
                    777:                                /* fetch u.u_signo from the child */
                    778: 
                    779:                                /* Find u area for child process pp */
                    780:                                sp = pp->p_segp[SIUSERP];
                    781:                                childUseg = MAPIO(sp->s_vmem, U_OFFSET);
                    782:                                work = workAlloc();
                    783:                                ptable1_v[work] =
                    784:                                  sysmem.u.pbase[btocrd(childUseg)] | SEG_RW;
                    785:                                mmuupd();
                    786:                                uprc = (UPROC *) (ctob(work) + U_OFFSET);
                    787:                                u.u_rval2 = ((uprc->u_signo)<<8) | 0177;
                    788:                                workFree(work);
                    789: 
                    790:                                unlock(pnxgate);
                    791:                                return pp->p_pid;
                    792:                        }
                    793: 
                    794:                        /* Here is an acceptable child that is a zombie. */
                    795:                        if (pp->p_state == PSDEAD) {
                    796:                                ppp->p_cutime += pp->p_utime + pp->p_cutime;
                    797:                                ppp->p_cstime += pp->p_stime + pp->p_cstime;
                    798:                                u.u_rval2 = pp->p_exit;
                    799:                                pid = pp->p_pid;
                    800:                                unlock(pnxgate);
                    801:                                relproc(pp);
                    802:                                if (SIG_BIT(SIGCLD) & ppp->p_isig)
                    803:                                        continue;
                    804:                                else {
                    805:                                        return pid;
                    806:                                }
                    807:                        }
                    808:                        cpp = pp;
                    809:                }
                    810:                unlock(pnxgate);
                    811:                if (cpp == NULL) {
                    812:                        u.u_error = ECHILD;
                    813:                        return;
                    814:                }
                    815: 
                    816:                if (options & WNOHANG) {
                    817:                                u.u_rval2 = 0;
                    818:                        return 0;
                    819:                }
                    820:                else
                    821:                        /* Wait for a child to terminate. */
                    822:                        x_s = x_sleep((char *)ppp, prilo, slpriSigLjmp,
                    823:                          "waitpid");
                    824:        }
                    825: }

unix.superglobalmegacorp.com

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