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

unix.superglobalmegacorp.com

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