Annotation of Net2/kern/kern_prot.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1989, 1990, 1991 Regents of the University
                      3:  * of California.  All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
1.1.1.3 ! root       33:  *     from: @(#)kern_prot.c   7.21 (Berkeley) 5/3/91
        !            34:  *     kern_prot.c,v 1.4 1993/07/13 22:13:23 cgd Exp
1.1       root       35:  */
                     36: 
                     37: /*
                     38:  * System calls related to processes and protection
                     39:  */
                     40: 
                     41: #include "param.h"
                     42: #include "acct.h"
                     43: #include "systm.h"
                     44: #include "ucred.h"
                     45: #include "proc.h"
                     46: #include "timeb.h"
                     47: #include "times.h"
                     48: #include "malloc.h"
                     49: 
                     50: /* ARGSUSED */
1.1.1.3 ! root       51: int
1.1       root       52: getpid(p, uap, retval)
                     53:        struct proc *p;
                     54:        void *uap;
                     55:        int *retval;
                     56: {
                     57: 
                     58:        *retval = p->p_pid;
                     59: #ifdef COMPAT_43
                     60:        retval[1] = p->p_pptr->p_pid;
                     61: #endif
                     62:        return (0);
                     63: }
                     64: 
                     65: /* ARGSUSED */
1.1.1.3 ! root       66: int
1.1       root       67: getppid(p, uap, retval)
                     68:        struct proc *p;
                     69:        void *uap;
                     70:        int *retval;
                     71: {
                     72: 
                     73:        *retval = p->p_pptr->p_pid;
                     74:        return (0);
                     75: }
                     76: 
                     77: /* Get process group ID; note that POSIX getpgrp takes no parameter */
1.1.1.3 ! root       78: int
1.1       root       79: getpgrp(p, uap, retval)
                     80:        struct proc *p;
                     81:        void *uap;
                     82:        int *retval;
                     83: {
                     84: 
                     85:        *retval = p->p_pgrp->pg_id;
                     86:        return (0);
                     87: }
                     88: 
                     89: /* ARGSUSED */
1.1.1.3 ! root       90: int
1.1       root       91: getuid(p, uap, retval)
                     92:        struct proc *p;
                     93:        void *uap;
                     94:        int *retval;
                     95: {
                     96: 
                     97:        *retval = p->p_cred->p_ruid;
                     98: #ifdef COMPAT_43
                     99:        retval[1] = p->p_ucred->cr_uid;
                    100: #endif
                    101:        return (0);
                    102: }
                    103: 
                    104: /* ARGSUSED */
1.1.1.3 ! root      105: int
1.1       root      106: geteuid(p, uap, retval)
                    107:        struct proc *p;
                    108:        void *uap;
                    109:        int *retval;
                    110: {
                    111: 
                    112:        *retval = p->p_ucred->cr_uid;
                    113:        return (0);
                    114: }
                    115: 
                    116: /* ARGSUSED */
1.1.1.3 ! root      117: int
1.1       root      118: getgid(p, uap, retval)
                    119:        struct proc *p;
                    120:        void *uap;
                    121:        int *retval;
                    122: {
                    123: 
                    124:        *retval = p->p_cred->p_rgid;
                    125: #ifdef COMPAT_43
                    126:        retval[1] = p->p_ucred->cr_groups[0];
                    127: #endif
                    128:        return (0);
                    129: }
                    130: 
                    131: /*
                    132:  * Get effective group ID.  The "egid" is groups[0], and could be obtained
                    133:  * via getgroups.  This syscall exists because it is somewhat painful to do
                    134:  * correctly in a library function.
                    135:  */
                    136: /* ARGSUSED */
1.1.1.3 ! root      137: int
1.1       root      138: getegid(p, uap, retval)
                    139:        struct proc *p;
                    140:        void *uap;
                    141:        int *retval;
                    142: {
                    143: 
                    144:        *retval = p->p_ucred->cr_groups[0];
                    145:        return (0);
                    146: }
                    147: 
1.1.1.3 ! root      148: struct getgroups_args {
        !           149:        u_int   gidsetsize;
        !           150:        int     *gidset;                /* XXX not yet POSIX */
        !           151: };
        !           152: 
        !           153: int
1.1       root      154: getgroups(p, uap, retval)
                    155:        struct proc *p;
1.1.1.3 ! root      156:        register struct getgroups_args *uap;
1.1       root      157:        int *retval;
                    158: {
                    159:        register struct pcred *pc = p->p_cred;
                    160:        register gid_t *gp;
                    161:        register int *lp;
                    162:        register u_int ngrp;
                    163:        int groups[NGROUPS];
                    164:        int error;
                    165: 
                    166:        if ((ngrp = uap->gidsetsize) == 0) {
                    167:                *retval = pc->pc_ucred->cr_ngroups;
                    168:                return (0);
                    169:        }
                    170:        if (ngrp < pc->pc_ucred->cr_ngroups)
                    171:                return (EINVAL);
                    172:        ngrp = pc->pc_ucred->cr_ngroups;
                    173:        for (gp = pc->pc_ucred->cr_groups, lp = groups; lp < &groups[ngrp]; )
                    174:                *lp++ = *gp++;
                    175:        if (error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
                    176:            ngrp * sizeof (groups[0])))
                    177:                return (error);
                    178:        *retval = ngrp;
                    179:        return (0);
                    180: }
                    181: 
                    182: /* ARGSUSED */
1.1.1.3 ! root      183: int
1.1       root      184: setsid(p, uap, retval)
                    185:        register struct proc *p;
                    186:        void *uap;
                    187:        int *retval;
                    188: {
                    189: 
                    190:        if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
                    191:                return (EPERM);
                    192:        } else {
                    193:                enterpgrp(p, p->p_pid, 1);
                    194:                *retval = p->p_pid;
                    195:                return (0);
                    196:        }
                    197: }
                    198: 
                    199: /*
                    200:  * set process group (setpgid/old setpgrp)
                    201:  *
                    202:  * caller does setpgid(targpid, targpgid)
                    203:  *
                    204:  * pid must be caller or child of caller (ESRCH)
                    205:  * if a child
                    206:  *     pid must be in same session (EPERM)
                    207:  *     pid can't have done an exec (EACCES)
                    208:  * if pgid != pid
                    209:  *     there must exist some pid in same session having pgid (EPERM)
                    210:  * pid must not be session leader (EPERM)
                    211:  */
1.1.1.3 ! root      212: 
        !           213: struct setpgid_args {
        !           214:        int     pid;    /* target process id */
        !           215:        int     pgid;   /* target pgrp id */
        !           216: };
        !           217: 
1.1       root      218: /* ARGSUSED */
1.1.1.3 ! root      219: int
1.1       root      220: setpgid(curp, uap, retval)
                    221:        struct proc *curp;
1.1.1.3 ! root      222:        register struct setpgid_args *uap;
1.1       root      223:        int *retval;
                    224: {
                    225:        register struct proc *targp;            /* target process */
                    226:        register struct pgrp *pgrp;             /* target pgrp */
                    227: 
                    228:        if (uap->pid != 0 && uap->pid != curp->p_pid) {
                    229:                if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
                    230:                        return (ESRCH);
                    231:                if (targp->p_session != curp->p_session)
                    232:                        return (EPERM);
                    233:                if (targp->p_flag&SEXEC)
                    234:                        return (EACCES);
                    235:        } else
                    236:                targp = curp;
                    237:        if (SESS_LEADER(targp))
                    238:                return (EPERM);
                    239:        if (uap->pgid == 0)
                    240:                uap->pgid = targp->p_pid;
                    241:        else if (uap->pgid != targp->p_pid)
                    242:                if ((pgrp = pgfind(uap->pgid)) == 0 ||
                    243:                    pgrp->pg_session != curp->p_session)
                    244:                        return (EPERM);
                    245:        enterpgrp(targp, uap->pgid, 0);
                    246:        return (0);
                    247: }
                    248: 
1.1.1.3 ! root      249: struct setuid_args {
        !           250:        int     uid;
        !           251: };
        !           252: 
1.1       root      253: /* ARGSUSED */
1.1.1.3 ! root      254: int
1.1       root      255: setuid(p, uap, retval)
                    256:        struct proc *p;
1.1.1.3 ! root      257:        struct setuid_args *uap;
1.1       root      258:        int *retval;
                    259: {
                    260:        register struct pcred *pc = p->p_cred;
                    261:        register uid_t uid;
                    262:        int error;
                    263: 
                    264:        uid = uap->uid;
                    265:        if (uid != pc->p_ruid &&
                    266:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    267:                return (error);
                    268:        /*
                    269:         * Everything's okay, do it.  Copy credentials so other references do
                    270:         * not see our changes.
                    271:         */
                    272:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    273:        pc->pc_ucred->cr_uid = uid;
                    274:        pc->p_ruid = uid;
                    275:        pc->p_svuid = uid;
                    276:        return (0);
                    277: }
                    278: 
1.1.1.3 ! root      279: struct seteuid_args {
        !           280:        int     euid;
        !           281: };
        !           282: 
1.1       root      283: /* ARGSUSED */
1.1.1.3 ! root      284: int
1.1       root      285: seteuid(p, uap, retval)
                    286:        struct proc *p;
1.1.1.3 ! root      287:        struct seteuid_args *uap;
1.1       root      288:        int *retval;
                    289: {
                    290:        register struct pcred *pc = p->p_cred;
                    291:        register uid_t euid;
                    292:        int error;
                    293: 
                    294:        euid = uap->euid;
                    295:        if (euid != pc->p_ruid && euid != pc->p_svuid &&
                    296:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    297:                return (error);
                    298:        /*
                    299:         * Everything's okay, do it.  Copy credentials so other references do
                    300:         * not see our changes.
                    301:         */
                    302:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    303:        pc->pc_ucred->cr_uid = euid;
                    304:        return (0);
                    305: }
                    306: 
1.1.1.3 ! root      307: struct setgid_args {
        !           308:        int     gid;
        !           309: };
        !           310: 
1.1       root      311: /* ARGSUSED */
1.1.1.3 ! root      312: int
1.1       root      313: setgid(p, uap, retval)
                    314:        struct proc *p;
1.1.1.3 ! root      315:        struct setgid_args *uap;
1.1       root      316:        int *retval;
                    317: {
                    318:        register struct pcred *pc = p->p_cred;
                    319:        register gid_t gid;
                    320:        int error;
                    321: 
                    322:        gid = uap->gid;
                    323:        if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    324:                return (error);
                    325:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    326:        pc->pc_ucred->cr_groups[0] = gid;
                    327:        pc->p_rgid = gid;
                    328:        pc->p_svgid = gid;              /* ??? */
                    329:        return (0);
                    330: }
                    331: 
1.1.1.3 ! root      332: struct setegid_args {
        !           333:        int     egid;
        !           334: };
        !           335: 
1.1       root      336: /* ARGSUSED */
1.1.1.3 ! root      337: int
1.1       root      338: setegid(p, uap, retval)
                    339:        struct proc *p;
1.1.1.3 ! root      340:        struct setegid_args *uap;
1.1       root      341:        int *retval;
                    342: {
                    343:        register struct pcred *pc = p->p_cred;
                    344:        register gid_t egid;
                    345:        int error;
                    346: 
                    347:        egid = uap->egid;
                    348:        if (egid != pc->p_rgid && egid != pc->p_svgid &&
                    349:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    350:                return (error);
                    351:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    352:        pc->pc_ucred->cr_groups[0] = egid;
                    353:        return (0);
                    354: }
                    355: 
                    356: #ifdef COMPAT_43
1.1.1.3 ! root      357: 
        !           358: struct osetreuid_args {
        !           359:        int     ruid;
        !           360:        int     euid;
        !           361: };
        !           362: 
1.1       root      363: /* ARGSUSED */
1.1.1.3 ! root      364: int
1.1       root      365: osetreuid(p, uap, retval)
                    366:        register struct proc *p;
1.1.1.3 ! root      367:        struct osetreuid_args *uap;
1.1       root      368:        int *retval;
                    369: {
                    370:        register struct pcred *pc = p->p_cred;
                    371:        register uid_t ruid, euid;
                    372:        int error;
                    373: 
                    374:        if (uap->ruid == -1)
                    375:                ruid = pc->p_ruid;
                    376:        else
                    377:                ruid = uap->ruid;
                    378:        /*
                    379:         * Allow setting real uid to previous effective, for swapping real and
                    380:         * effective.  This should be:
                    381:         *
                    382:         * if (ruid != pc->p_ruid &&
                    383:         *     (error = suser(pc->pc_ucred, &p->p_acflag)))
                    384:         */
                    385:        if (ruid != pc->p_ruid && ruid != pc->pc_ucred->cr_uid /* XXX */ &&
                    386:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    387:                return (error);
                    388:        if (uap->euid == -1)
                    389:                euid = pc->pc_ucred->cr_uid;
                    390:        else
                    391:                euid = uap->euid;
                    392:        if (euid != pc->pc_ucred->cr_uid && euid != pc->p_ruid &&
                    393:            euid != pc->p_svuid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    394:                return (error);
                    395:        /*
                    396:         * Everything's okay, do it.  Copy credentials so other references do
                    397:         * not see our changes.
                    398:         */
                    399:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    400:        pc->pc_ucred->cr_uid = euid;
                    401:        pc->p_ruid = ruid;
                    402:        return (0);
                    403: }
                    404: 
1.1.1.3 ! root      405: struct osetregid_args {
        !           406:        int     rgid;
        !           407:        int     egid;
        !           408: };
        !           409: 
1.1       root      410: /* ARGSUSED */
1.1.1.3 ! root      411: int
1.1       root      412: osetregid(p, uap, retval)
                    413:        register struct proc *p;
1.1.1.3 ! root      414:        struct osetregid_args *uap;
1.1       root      415:        int *retval;
                    416: {
                    417:        register struct pcred *pc = p->p_cred;
                    418:        register gid_t rgid, egid;
                    419:        int error;
                    420: 
                    421:        if (uap->rgid == -1)
                    422:                rgid = pc->p_rgid;
                    423:        else
                    424:                rgid = uap->rgid;
                    425:        /*
                    426:         * Allow setting real gid to previous effective, for swapping real and
                    427:         * effective.  This didn't really work correctly in 4.[23], but is
                    428:         * preserved so old stuff doesn't fail.  This should be:
                    429:         *
                    430:         * if (rgid != pc->p_rgid &&
                    431:         *     (error = suser(pc->pc_ucred, &p->p_acflag)))
                    432:         */
                    433:        if (rgid != pc->p_rgid && rgid != pc->pc_ucred->cr_groups[0] /* XXX */ &&
                    434:            (error = suser(pc->pc_ucred, &p->p_acflag)))
                    435:                return (error);
                    436:        if (uap->egid == -1)
                    437:                egid = pc->pc_ucred->cr_groups[0];
                    438:        else
                    439:                egid = uap->egid;
                    440:        if (egid != pc->pc_ucred->cr_groups[0] && egid != pc->p_rgid &&
                    441:            egid != pc->p_svgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
                    442:                return (error);
                    443:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    444:        pc->pc_ucred->cr_groups[0] = egid;
                    445:        pc->p_rgid = rgid;
                    446:        return (0);
                    447: }
                    448: #endif
                    449: 
1.1.1.3 ! root      450: struct setgroups_args {
        !           451:        u_int   gidsetsize;
        !           452:        int     *gidset;
        !           453: };
        !           454: 
1.1       root      455: /* ARGSUSED */
1.1.1.3 ! root      456: int
1.1       root      457: setgroups(p, uap, retval)
                    458:        struct proc *p;
1.1.1.3 ! root      459:        struct setgroups_args *uap;
1.1       root      460:        int *retval;
                    461: {
                    462:        register struct pcred *pc = p->p_cred;
                    463:        register gid_t *gp;
                    464:        register u_int ngrp;
                    465:        register int *lp;
                    466:        int error, groups[NGROUPS];
                    467: 
                    468:        if (error = suser(pc->pc_ucred, &p->p_acflag))
                    469:                return (error);
                    470:        if ((ngrp = uap->gidsetsize) > NGROUPS)
                    471:                return (EINVAL);
                    472:        if (error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
                    473:            ngrp * sizeof (groups[0])))
                    474:                return (error);
                    475:        pc->pc_ucred = crcopy(pc->pc_ucred);
                    476:        pc->pc_ucred->cr_ngroups = ngrp;
                    477:        /* convert from int's to gid_t's */
                    478:        for (gp = pc->pc_ucred->cr_groups, lp = groups; ngrp--; )
                    479:                *gp++ = *lp++;
                    480:        return (0);
                    481: }
                    482: 
                    483: /*
                    484:  * Check if gid is a member of the group set.
                    485:  */
1.1.1.3 ! root      486: int
1.1       root      487: groupmember(gid, cred)
                    488:        gid_t gid;
                    489:        register struct ucred *cred;
                    490: {
                    491:        register gid_t *gp;
                    492:        gid_t *egp;
                    493: 
                    494:        egp = &(cred->cr_groups[cred->cr_ngroups]);
                    495:        for (gp = cred->cr_groups; gp < egp; gp++)
                    496:                if (*gp == gid)
                    497:                        return (1);
                    498:        return (0);
                    499: }
                    500: 
                    501: /*
                    502:  * Test whether the specified credentials imply "super-user"
                    503:  * privilege; if so, and we have accounting info, set the flag
                    504:  * indicating use of super-powers.
                    505:  * Returns 0 or error.
                    506:  */
1.1.1.3 ! root      507: int
1.1       root      508: suser(cred, acflag)
                    509:        struct ucred *cred;
1.1.1.2   root      510:        u_short *acflag;
1.1       root      511: {
                    512:        if (cred->cr_uid == 0) {
                    513:                if (acflag)
                    514:                        *acflag |= ASU;
                    515:                return (0);
                    516:        }
                    517:        return (EPERM);
                    518: }
                    519: 
                    520: /*
                    521:  * Allocate a zeroed cred structure.
                    522:  */
                    523: struct ucred *
                    524: crget()
                    525: {
                    526:        register struct ucred *cr;
                    527: 
                    528:        MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
                    529:        bzero((caddr_t)cr, sizeof(*cr));
                    530:        cr->cr_ref = 1;
                    531:        return (cr);
                    532: }
                    533: 
                    534: /*
                    535:  * Free a cred structure.
                    536:  * Throws away space when ref count gets to 0.
                    537:  */
1.1.1.3 ! root      538: void
1.1       root      539: crfree(cr)
                    540:        struct ucred *cr;
                    541: {
                    542:        int s = splimp();                       /* ??? */
                    543: 
                    544:        if (--cr->cr_ref != 0) {
                    545:                (void) splx(s);
                    546:                return;
                    547:        }
                    548:        FREE((caddr_t)cr, M_CRED);
                    549:        (void) splx(s);
                    550: }
                    551: 
                    552: /*
                    553:  * Copy cred structure to a new one and free the old one.
                    554:  */
                    555: struct ucred *
                    556: crcopy(cr)
                    557:        struct ucred *cr;
                    558: {
                    559:        struct ucred *newcr;
                    560: 
                    561:        if (cr->cr_ref == 1)
                    562:                return (cr);
                    563:        newcr = crget();
                    564:        *newcr = *cr;
                    565:        crfree(cr);
                    566:        newcr->cr_ref = 1;
                    567:        return (newcr);
                    568: }
                    569: 
                    570: /*
                    571:  * Dup cred struct to a new held one.
                    572:  */
                    573: struct ucred *
                    574: crdup(cr)
                    575:        struct ucred *cr;
                    576: {
                    577:        struct ucred *newcr;
                    578: 
                    579:        newcr = crget();
                    580:        *newcr = *cr;
                    581:        newcr->cr_ref = 1;
                    582:        return (newcr);
                    583: }
                    584: 
                    585: /*
                    586:  * Get login name, if available.
                    587:  */
1.1.1.3 ! root      588: 
        !           589: struct getlogin_args {
        !           590:        char    *namebuf;
        !           591:        u_int   namelen;
        !           592: };
        !           593: 
1.1       root      594: /* ARGSUSED */
1.1.1.3 ! root      595: int
1.1       root      596: getlogin(p, uap, retval)
                    597:        struct proc *p;
1.1.1.3 ! root      598:        struct getlogin_args *uap;
1.1       root      599:        int *retval;
                    600: {
                    601: 
                    602:        if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
                    603:                uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
                    604:        return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
                    605:            (caddr_t) uap->namebuf, uap->namelen));
                    606: }
                    607: 
                    608: /*
                    609:  * Set login name.
                    610:  */
1.1.1.3 ! root      611: 
        !           612: struct setlogin_args {
        !           613:        char    *namebuf;
        !           614: };
        !           615: 
1.1       root      616: /* ARGSUSED */
1.1.1.3 ! root      617: int
1.1       root      618: setlogin(p, uap, retval)
                    619:        struct proc *p;
1.1.1.3 ! root      620:        struct setlogin_args *uap;
1.1       root      621:        int *retval;
                    622: {
                    623:        int error;
                    624: 
                    625:        if (error = suser(p->p_ucred, &p->p_acflag))
                    626:                return (error);
                    627:        error = copyinstr((caddr_t) uap->namebuf,
                    628:            (caddr_t) p->p_pgrp->pg_session->s_login,
                    629:            sizeof (p->p_pgrp->pg_session->s_login) - 1, (u_int *)0);
                    630:        if (error == ENAMETOOLONG)
                    631:                error = EINVAL;
                    632:        return (error);
                    633: }

unix.superglobalmegacorp.com

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