Annotation of 43BSD/games/compat/unixtraps.c, revision 1.1.1.1

1.1       root        1: #ifndef        lint
                      2: static char sccsid[] = "@(#)unixtraps.c        4.3 84/05/05";
                      3: #endif
                      4: 
                      5: /* From Lou Salkind: compat/RCS/unixtraps.c,v 1.2 84/01/31 13:34:34 */
                      6: 
                      7: /*
                      8:  * Function to execute version 6 and version 7 UNIX system calls from
                      9:  * compatability mode on UNIX-32V.
                     10:  *     Art Wetzel      August 1979
                     11:  */
                     12: 
                     13: #include <stdio.h>
                     14: #include <signal.h>
                     15: #include <sys/types.h>
                     16: #include <sys/stat.h>
                     17: #include <sys/ioctl.h>
                     18: #include <sys/time.h>
                     19: #include <sys/dir.h>
                     20: #ifdef V6UNIX
                     21: #ifdef TRACE
                     22: #define        RTSNAME "/../../../../usr/local/v6trc"
                     23: #else
                     24: #define        RTSNAME "/../../../../usr/local/v6run"
                     25: #endif
                     26: #include "unix6sys.h"
                     27: #ifdef TRACE
                     28: #include "unix6sysn.h"
                     29: #endif
                     30: #endif
                     31: #ifdef V7UNIX
                     32: #ifdef TRACE
                     33: #define        RTSNAME "/../../../../usr/local/v7trc"
                     34: #else
                     35: #define        RTSNAME "/../../../../usr/local/v7run"
                     36: #endif
                     37: #include "unix7sys.h"
                     38: #ifdef TRACE
                     39: #include "unix7sysn.h"
                     40: #endif
                     41: #endif
                     42: #include "defs.h"
                     43: #define        CARRY   1
                     44: #define        MAXSARGS        100
                     45: #ifdef V6UNIX
                     46: #define        ARGVLEN 512
                     47: #define        ENVLEN  0
                     48: #endif
                     49: #ifdef V7UNIX
                     50: #define        ARGVLEN 5120
                     51: #define        ENVLEN  1000
                     52: #endif
                     53: char   argvs[ARGVLEN+ENVLEN];
                     54: int    args[MAXSARGS];
                     55: 
                     56: /* 32v type stat structure */
                     57: extern struct  stat    stat32v;
                     58: 
                     59: /* place for times data so we can reverse the longs */
                     60: struct timebuf {
                     61:        long    t1;
                     62:        long    t2;
                     63:        long    t3;
                     64:        long    t4;
                     65: } timebuf;
                     66: 
                     67: /* place for pipe file descriptors */
                     68: int    pipes[2];
                     69: 
                     70: /* wait status */
                     71: int    wstatus;
                     72: 
                     73: #ifdef V6UNIX
                     74: /* version 6 style stat structure */
                     75: struct v6nod {
                     76:        dev_t   majmin;
                     77:        ino_t   inumber;
                     78:        unsigned short  flags;
                     79:        unsigned char   nlinks;
                     80:        unsigned char   uid;
                     81:        unsigned char   gid;
                     82:        unsigned char   size0;
                     83:        unsigned short  size1;
                     84:        unsigned short  addr[8];
                     85:        long    actime;
                     86:        long    modtime;
                     87: } *v6stat;
                     88: #endif
                     89: 
                     90: #ifdef V7UNIX
                     91: /* version 7 style stat structure */
                     92: struct v7stat {
                     93:        dev_t   v7st_dev;
                     94:        u_short v7st_ino;
                     95:        u_short v7st_mode;
                     96:        short   v7st_nlink;
                     97:        short   v7st_uid;
                     98:        short   v7st_gid;
                     99:        dev_t   v7st_rdev;
                    100:        int     v7st_size;
                    101:        int     v7st_atime;
                    102:        int     v7st_mtime;
                    103:        int     v7st_ctime;
                    104: } statv7;
                    105: 
                    106: struct timeb {
                    107:        time_t  time;
                    108:        u_short millitm;
                    109:        short   timezone;
                    110:        short   dstflag;
                    111: } timeb;
                    112: #endif
                    113: 
                    114: #define        NFILES  20
                    115: #define        ODSIZE  16
                    116: 
                    117: off_t  olseek();
                    118: 
                    119: struct odirect {
                    120:        u_short od_ino;
                    121:        char    od_name[14];
                    122: };
                    123: 
                    124: struct fdflags {
                    125:        DIR     *fd_dirp;
                    126:        struct odirect  fd_od;
                    127:        off_t   fd_offset;
                    128: } fdflags[NFILES];
                    129: 
                    130: /* do the trap stuff for the trap with code */
                    131: dotrap(code)
                    132:        int code;
                    133: {
                    134:        register unsigned short *argp, *savp, *savep;
                    135:        register int i, j, indirflg;
                    136:        register char *avp, *oavp;
                    137:        extern sigcatch();
                    138:        extern errno;
                    139:        extern int sigtrapped;
                    140:        DIR *dp;
                    141: 
                    142:        sigtrapped = 0;
                    143:        /* clear out condition codes of psl */
                    144:        psl &= ~017;
                    145:        /* special case of indirect sys call */
                    146:        if (code == 0) {
                    147:                /* remember this was indirect */
                    148:                indirflg = 1;
                    149:                /* point to args */
                    150:                argp = (unsigned short *)*(pc++);
                    151:                /* code for indirect sys call */
                    152:                code = *argp++;
                    153:                /* is it legit */
                    154:                if (code>>8 != TRAPS) {
                    155:                        fprintf(stderr,"Bad indirect sys call at 0x%x\n",pc-2);
                    156:                        pc++;
                    157:                        /* set carry flag */
                    158:                        psl |= CARRY;
                    159:                        regs[0] = -1;
                    160:                        return(-1);
                    161:                }
                    162:                code &= 0377;
                    163:        } else {
                    164:                /* remember this was not indirect */
                    165:                indirflg = 0;
                    166:                /* point to args */
                    167:                argp = pc;
                    168:        }
                    169:        /* check if code too high or bad sys code */
                    170:        if (code >= NSYSTRAPS || sysargs[code][0] == ILLSYS) {
                    171:                fprintf(stderr,"Unimplimented trap %d at 0x%x\n",code,argp);
                    172:                /* set carry bit */
                    173:                psl |= CARRY;
                    174:                regs[0] = -1;
                    175:                return(-1);
                    176:        }
                    177:        /* copy args to known locations */
                    178:        i=0;
                    179:        for (j=0; j<sysargs[code][0]; j++)
                    180:                args[i++] = regs[j];
                    181:        for (j=0; j<(sysargs[code][1]); j++)
                    182:                args[i++] = *argp++;
                    183: #ifdef TRACE
                    184:        fprintf(stderr,"pid %d ",getpid());
                    185:        if (indirflg)
                    186:                fprintf(stderr,"indirect ");
                    187:        fprintf(stderr, "%s (%d) from 0%o with %d args",
                    188:            sysnames[code], code, pc-1, i);
                    189:        for (j=0; j<i; j++)
                    190:                fprintf(stderr," 0%o",args[j]);
                    191:        if (code==OPEN || code==STAT || code==CREAT || code==EXEC || 
                    192:            code==UNLNK || code==LINK || code==CHDIR || code==MKNOD)
                    193:                fprintf(stderr," (%s)",args[0]);
                    194: #ifdef V7UNIX
                    195:        if (code==EXECE)
                    196:                fprintf(stderr," (%s)",args[0]);
                    197: #endif
                    198:        if (code==LINK)
                    199:                fprintf(stderr," (%s)",args[1]);
                    200: #endif
                    201:        /* go do whatever sys call it is */
                    202:        switch (code) {
                    203:        case FORK:
                    204:                /* indirect forks return pids on both sides - must do here */
                    205:                /* this is possibly a bug in 32V */
                    206:                i = fork();
                    207:                break;
                    208: 
                    209:        case WAIT:
                    210:                i = wait(&wstatus);
                    211:                args[0] = i;
                    212:                args[1] = wstatus;
                    213:                break;
                    214: 
                    215:        case EXEC:
                    216: #ifdef V7UNIX
                    217:        case EXECE:
                    218: #endif
                    219:                /*
                    220:                 *  have to do a lot of junk here to fix up an argv
                    221:                 *  for execute since (1) the pdp-11 argv consists of 16
                    222:                 *  bit pointers and (2) the argv itself is in the
                    223:                 *  pdp-11 program space where it would get clobbered
                    224:                 *  when a new program is read in and before its
                    225:                 *  argv is set up.
                    226:                 */
                    227:                avp = &argvs[0];
                    228:                savp = (unsigned short *)args[1];
                    229: #ifdef V6UNIX
                    230:                for (i=1; args[i] = *savp++; i++)
                    231:                        if (args[i] == 0177777)
                    232:                                break;
                    233: #ifdef TRACE
                    234:                        else
                    235:                                fprintf(stderr,"argv[%d]%s ",i-1,args[i]);
                    236: #endif
                    237: #endif
                    238: #ifdef V7UNIX
                    239:                savep = (unsigned short *)args[2];
                    240:                for (i=1; args[i] = *savp++; i++)
                    241: #ifdef TRACE
                    242:                        fprintf(stderr,"argv[%d]%s ",i-1,args[i]);
                    243: #else
                    244:                        ;
                    245: #endif
                    246: #endif
                    247:                if (stat(args[0], &stat32v)) {
                    248:                        /* return error here if file does not exist */
                    249: #ifdef TRACE
                    250:                        fprintf(stderr," does not exist\n");
                    251: #endif
                    252:                        i = -1;
                    253:                        break;
                    254:                }
                    255:                /* must have execute permission */
                    256:                if (stat32v.st_mode & (S_IEXEC>>6))
                    257:                        goto experm;
                    258:                if (stat32v.st_mode & (S_IEXEC>>3)) {
                    259:                        if (stat32v.st_gid == getegid())
                    260:                                goto experm;
                    261:                        if (geteuid() == 0)
                    262:                                goto experm;
                    263:                }
                    264:                if (stat32v.st_mode & S_IEXEC) {
                    265:                        if (stat32v.st_uid == geteuid())
                    266:                                goto experm;
                    267:                        if (geteuid() == 0)
                    268:                                goto experm;
                    269:                }
                    270:                /* return failure if no exec permision allowed */
                    271:                i = -1;
                    272: experm:
                    273:                /* can't exec a directory */
                    274:                if ((stat32v.st_mode&S_IFMT) == S_IFDIR)
                    275:                        i = -1;
                    276:                if (i == -1)
                    277:                        break;
                    278:                args[i] = 0;
                    279:                for (j=1; j<i; j++) {
                    280:                        oavp = (char *)args[j];
                    281:                        args[j] = (int)avp;
                    282:                        while (*avp++ = *oavp++)
                    283:                                ;
                    284:                }
                    285: #ifdef V7UNIX
                    286:                if (code == EXECE) {
                    287:                        for (j = ++i; args[j] = *savep++; j++)
                    288:                                ;
                    289:                        for (j = i; oavp = (char *)args[j]; j++) {
                    290:                                args[j] = (int)avp;
                    291:                                while (*avp++ = *oavp++)
                    292:                                        ;
                    293:                        }
                    294:                }
                    295: #endif
                    296:                /* SETUID and SETGID files must be started with a fresh RTS */
                    297:                if (stat32v.st_mode & S_ISGID || stat32v.st_mode & S_ISUID) {
                    298:                        /* should add a check here for good magic # in header */
                    299:                        args[1] = args[0];
                    300:                        args[0] = (int)RTSNAME;
                    301: #ifdef TRACE
                    302:                        fprintf(stderr," SETUID-GID");
                    303: #endif
                    304:                        if (args[i])
                    305:                                i = execve(args[0], &args[0], &args[i]);
                    306:                        else
                    307:                                i = execv(args[0], &args[0]);
                    308:                        fprintf(stderr,"can't exec %s\n",RTSNAME);
                    309:                        break;
                    310:                }
                    311:                i = execute(args[0], &args[1], &args[i]);
                    312:                /* shouldn't get here if exec works */
                    313:                break;
                    314: 
                    315:        case SEEK:
                    316: #ifdef V6UNIX
                    317:                /* fix up negative offsets */
                    318:                if (args[2] != 0 && args[2] != 3)
                    319:                        if (args[1] >= 32768)
                    320:                                args[1] -= 65536;
                    321:                if (args[2] <= 2)
                    322:                        i = olseek(args[0], args[1], args[2]);
                    323:                else
                    324:                        i = olseek(args[0], args[1]*512, args[2]-3);
                    325:                if (i != -1)
                    326:                        i = 0;
                    327: #endif
                    328: #ifdef V7UNIX
                    329:                i = olseek(args[0], (args[1]<<16)|(args[2]&0177777), args[3]);
                    330: #endif
                    331:                break;
                    332: 
                    333:        case MKNOD:
                    334:                if ((args[1] & S_IFMT) == S_IFDIR)
                    335:                        i = mkdir(args[0], args[1] & 0777);
                    336:                else {
                    337: #ifdef V6UNIX
                    338:                        /*
                    339:                         * version 6 uses allocated bit which
                    340:                         * means regular file here
                    341:                         */
                    342:                        if (args[1] & S_IFBLK)
                    343:                                args[1] &= ~S_IFREG;
                    344: #endif 
                    345:                        i = mknod(args[0], args[1], args[2]);
                    346:                }
                    347:                break;
                    348: 
                    349:        case PIPE:
                    350:                i = pipe(pipes);
                    351:                args[0] = pipes[0];
                    352:                args[1] = pipes[1];
                    353:                break;
                    354: 
                    355: #ifdef V6UNIX
                    356:        case TELL:
                    357:                i = lseek(args[0], 0L, 1);
                    358:                break;
                    359: 
                    360:        case STTY:
                    361:                i = stty(args[0], args[1]);
                    362:                break;
                    363: 
                    364:        case GTTY:
                    365:                i = gtty(args[0], args[1]);
                    366:                break;
                    367: #endif
                    368: 
                    369:        /* HAVE TO FAKE THE SIZE OF DIRECTORIES */
                    370: 
                    371:        case STAT:
                    372:                i = stat(args[0], &stat32v);
                    373:                goto allstat;
                    374: 
                    375:        case FSTAT:
                    376:                /* do the syscall to a local stat buffer */
                    377:                i = fstat(args[0], &stat32v);
                    378: 
                    379:        allstat:
                    380:                /* reverse the longs */
                    381:                stat32v.st_size = longrev(stat32v.st_size);
                    382:                stat32v.st_atime = longrev(stat32v.st_atime);
                    383:                stat32v.st_mtime = longrev(stat32v.st_mtime);
                    384:                stat32v.st_ctime = longrev(stat32v.st_ctime);
                    385: #ifdef V7UNIX
                    386:                statv7.v7st_dev = stat32v.st_dev;
                    387:                statv7.v7st_ino = stat32v.st_ino;
                    388:                statv7.v7st_mode = stat32v.st_mode;
                    389:                statv7.v7st_nlink = stat32v.st_nlink;
                    390:                statv7.v7st_uid = stat32v.st_uid;
                    391:                statv7.v7st_gid = stat32v.st_gid;
                    392:                statv7.v7st_rdev = stat32v.st_rdev;
                    393:                statv7.v7st_size = stat32v.st_size;
                    394:                statv7.v7st_atime = stat32v.st_atime;
                    395:                statv7.v7st_mtime = stat32v.st_mtime;
                    396:                statv7.v7st_ctime = stat32v.st_ctime;
                    397:                /* copy out otherwise unchanged stat buffer */
                    398:                /* in two pieces with st_size as the breaking point */
                    399:                /* note that st_rdev is a short but due to alingnmemt */
                    400:                /* problems the rest of the structure is out of sync */
                    401:                j = (int)((char *)(&statv7.v7st_size) -
                    402:                    (char *)(&statv7.v7st_dev));
                    403:                bcopy(&statv7, args[1], j);
                    404:                bcopy(&statv7.v7st_size, args[1]+j-2, sizeof(struct v7stat)-j);
                    405: #endif
                    406: #ifdef V6UNIX
                    407:                /* point to user area as v6stat structure */
                    408:                v6stat = (struct v6nod *)args[1];
                    409:                /* copy out piece by piece */
                    410:                v6stat->majmin = stat32v.st_dev;
                    411:                v6stat->inumber = stat32v.st_ino;
                    412:                v6stat->flags = stat32v.st_mode;
                    413:                v6stat->nlinks = (unsigned char)stat32v.st_nlink;
                    414:                v6stat->uid = (unsigned char)stat32v.st_uid;
                    415:                v6stat->gid = (unsigned char)stat32v.st_gid;
                    416:                /* note size already reversed */
                    417:                v6stat->size0 = (unsigned char)(stat32v.st_size & 0377);
                    418:                v6stat->size1 = (unsigned short)(stat32v.st_size>>16);
                    419:                v6stat->actime = stat32v.st_atime;
                    420:                v6stat->modtime = stat32v.st_mtime;
                    421:                /* patch up flags */
                    422:                /* for now just set 100000 bit if not a plain file */
                    423:                if (v6stat->flags & 060000)
                    424:                        v6stat->flags |= 0100000;
                    425: #endif
                    426:                break;
                    427: 
                    428:        case TIMES:
                    429:                i = times(&timebuf);
                    430:                timebuf.t2 = longrev(timebuf.t2) + timebuf.t1;
                    431:                timebuf.t3 = longrev(timebuf.t3);
                    432:                timebuf.t4 = longrev(timebuf.t4);
                    433:                bcopy(&timebuf.t2,args[0],sizeof(struct timebuf)-sizeof(long));
                    434:                break;
                    435: 
                    436: #ifdef V6UNIX
                    437:        case SLEEP:
                    438:                /* do a sleep function - what about pwb which has alarm? */
                    439:                sleep(args[0]);
                    440:                break;
                    441: #endif
                    442: 
                    443:        case GETUID:
                    444:                args[0] = getuid();
                    445:                args[1] = geteuid();
                    446: #ifdef V6UNIX
                    447:                i = args[1]<<8 | (args[0] & 0377);
                    448: #endif
                    449:                break;
                    450: 
                    451:        case GETGID:
                    452:                args[0] = getgid();
                    453:                args[1] = getegid();
                    454: #ifdef V6UNIX
                    455:                i = args[1]<<8 | (args[0] & 0377);
                    456: #endif
                    457:                break;
                    458: 
                    459:                /* uids and gids are 8 bits in version 6 */
                    460:        case SETUID:
                    461:        case SETGID:
                    462: #ifdef V6UNIX
                    463:                args[0] &= 0377;
                    464: #endif
                    465:                if (code == SETUID)
                    466:                        i = setuid(args[0]);
                    467:                else
                    468:                        i = setgid(args[0]);
                    469:                break;
                    470: 
                    471:        case SIG:
                    472:                /* if it is a good signal code */
                    473:                if (args[0] <= NSIG) {
                    474:                        /* get the current signal value */
                    475:                        i = sigvals[args[0]];
                    476:                        /* reset the signal to the new value */
                    477:                        sigvals[args[0]] = args[1];
                    478:                        /* actually do signal except don't reset SIGILL */
                    479:                        if (args[0] != SIGILL) {
                    480:                                if (args[1] == (int)SIG_DFL ||
                    481:                                    args[1] & (int)SIG_IGN) {
                    482:                                        if ((int)signal(args[0],args[1]) == -1)
                    483:                                                i = -1;
                    484:                                } else {
                    485:                                        if ((int)signal(args[0],sigcatch) == -1)
                    486:                                                i = -1;
                    487:                                }
                    488:                        }
                    489:                } else
                    490:                        i = -1;
                    491:                break;
                    492: 
                    493:        case BRK:
                    494:                /* brk is successful unless we run over the stack */
                    495:                /* NB: this assumes register usage which need not be used */
                    496:                i = 0;
                    497:                if (args[0] >= regs[6])
                    498:                        i = -1;
                    499:                break;
                    500: 
                    501:        /*
                    502:         * the next bunch are to cope with sys calls removed from 4.2
                    503:         */
                    504:        case TIME:
                    505:                i = time(0);
                    506:                break;
                    507: 
                    508:        case STIME: {
                    509:                struct timeval tv;
                    510: 
                    511:                tv.tv_usec = 0;
                    512:                tv.tv_sec = (args[0] & 0xffff) | ((args[1] & 0xffff) << 16);
                    513:                i = settimeofday(&tv);
                    514:                break;
                    515:        }
                    516: 
                    517:        case NICE:
                    518:                i = nice(args[0]);
                    519:                break;
                    520: 
                    521: #ifdef V7UNIX
                    522:        case ALARM:
                    523:                i = alarm(args[0]);
                    524:                break;
                    525: 
                    526:        case PAUSE:
                    527:                i = pause();
                    528:                break;
                    529: 
                    530:        case UTIME:
                    531:                i = utime(args[0], args[1]);
                    532:                break;
                    533: 
                    534:        case FTIME:
                    535:                i = ftime(&timeb);
                    536:                timeb.time = longrev(timeb.time);
                    537:                bcopy(&timeb, args[0], sizeof timeb - 2);
                    538:                break;
                    539: 
                    540:        case IOCTL:
                    541:                args[1] = mapioctl(args[1]);
                    542:                if (args[1] == 0)
                    543:                        i = -1;
                    544:                else
                    545:                        i = ioctl(args[0], args[1], args[2]);
                    546:                break;
                    547: #endif
                    548: 
                    549: #ifdef V6UNIX
                    550:        case PWBSYS:
                    551:                /* ignore pwbsys for now */
                    552:                switch (args[2]) {
                    553:                case UNAME:
                    554: #ifdef TRACE
                    555:                        fprintf(stderr,"UNAME with %d %d\n",args[0],args[1]);
                    556: #endif
                    557:                        strcpy(args[0],"pwbname");
                    558:                        i = 0;
                    559:                        break;
                    560: 
                    561:                case UDATA:
                    562: #ifdef TRACE
                    563:                        fprintf(stderr,"UDATA with %d %d\n",args[0],args[1]);
                    564: #endif
                    565:                        i = 0;
                    566:                        break;
                    567: 
                    568:                case USTAT:
                    569: fprintf(stderr,"USTAT with %d %d\n",args[0],args[1]);
                    570:                        i = 0;
                    571:                        break;
                    572: 
                    573:                case UTIME:
                    574: fprintf(stderr,"UTIME with %d %d\n",args[0],args[1]);
                    575:                        i = 0;
                    576:                        break;
                    577:                default:
                    578: fprintf(stderr,"bad PWBSYS %d\n",args[3]);
                    579:                        i = -1;
                    580:                        break;
                    581:                }
                    582:                break;
                    583: #endif
                    584: 
                    585:        default:
                    586:                /*
                    587:                 *      Many sys calls are easily done here since most
                    588:                 *      system call codes are the same on version 6 and 7 UNIX
                    589:                 *      as they are here.
                    590:                 */
                    591:                i = syscall(code,args[0],args[1],args[2],args[3],args[4]);
                    592: #ifdef V6UNIX
                    593:                /* allow read write access to created files for (IDIS v6 mod) */
                    594:                if (code==CREAT) {
                    595:                        /* get actual file mode after create */
                    596:                        fstat(i, &stat32v);
                    597:                        close(i);
                    598:                        /* ensure read/write access to owner */
                    599:                        chmod(args[0], 0644);
                    600:                        i = open(args[0], 2);
                    601:                        /* change mode back the way it was */
                    602:                        chmod(args[0], stat32v.st_mode);
                    603:                }
                    604: #endif
                    605:                break;
                    606:        case OPEN:
                    607:                /*
                    608:                 * check if we are opening a directory
                    609:                 */
                    610:                if (stat(args[0], &stat32v) >= 0  &&
                    611:                    ((stat32v.st_mode & S_IFMT) == S_IFDIR) &&
                    612:                    ((dp = opendir(args[0])) != NULL)) {
                    613: #ifdef DTRACE
                    614:                        fprintf(stderr,"open directory fd %d\n", i);
                    615: #endif
                    616:                        i = dp->dd_fd;
                    617:                        fdflags[i].fd_dirp = dp;
                    618:                        fdflags[i].fd_offset = 0;
                    619:                } else
                    620:                        i = open(args[0], args[1]);
                    621:                break;
                    622:        case CLOSE:
                    623:                i = close(args[0]);
                    624:                if (i >= 0 && fdflags[args[0]].fd_dirp) {
                    625:                        closedir(fdflags[args[0]].fd_dirp);
                    626:                        fdflags[args[0]].fd_dirp = 0;
                    627:                }
                    628:                break;
                    629:        case READ:
                    630:                if ((unsigned)args[0] < NFILES && fdflags[args[0]].fd_dirp)
                    631:                        i = oread(args[0], args[1], args[2]);
                    632:                else
                    633:                        i = read(args[0], args[1], args[2]);
                    634:                break;
                    635:        }
                    636: #ifdef TRACE
                    637:        fprintf(stderr," sys val -> 0%o\n",i);
                    638: #endif
                    639:        /* set carry bit if sys error */
                    640:        if (i == -1)
                    641:                psl |= CARRY;
                    642:        /* if not an indirect sys call, adjust the pc */
                    643:        if (!indirflg && !sigtrapped)
                    644:                pc = argp;
                    645:        /* do alternate return on one side of fork */
                    646:        if (code == FORK && i != 0)
                    647:                pc++;
                    648:        /* do the various return value formats */
                    649:        switch (sysargs[code][2]) {
                    650:        case NORMRET:
                    651:                /* normal case only one return value in r0 */
                    652:                regs[0] = i;
                    653:                break;
                    654:        case LONGRET:
                    655:                /* return a long in r0 - r1 as in time */
                    656:                regs[1] = i;
                    657:                regs[0] = i >> 16;
                    658:                break;
                    659:        case TWORET:
                    660:                /* return two ints in r0 - r1 as in pipe */
                    661:                if (i == -1)
                    662:                        regs[0] = i;
                    663:                else {
                    664:                        regs[1] = args[1];
                    665:                        regs[0] = args[0];
                    666:                }
                    667:                break;
                    668:        }
                    669:        if (i== -1)
                    670:                regs[0] = errno;
                    671: }
                    672: 
                    673: long
                    674: longrev(l)
                    675:        long l;
                    676: {
                    677:        /* function to reverse the halves of a long */
                    678:        union {
                    679:                long    lng;
                    680:                short   s[2];
                    681:        } u;
                    682:        register short t;
                    683:        u.lng = l;
                    684:        t = u.s[0];
                    685:        u.s[0] = u.s[1];
                    686:        u.s[1] = t;
                    687:        return(u.lng);
                    688: }
                    689: 
                    690: /*
                    691:  * Note: these tables are sorted by
                    692:  * ioctl "code" (in ascending order).
                    693:  */
                    694: int fctls[] = { FIOCLEX, FIONCLEX, FIOASYNC, FIONBIO, FIONREAD, 0 };
                    695: int tctls[] = {
                    696:        TIOCGETD, TIOCSETD, TIOCHPCL, TIOCMODG, TIOCMODS,
                    697:        TIOCGETP, TIOCSETP, TIOCSETN, TIOCEXCL, TIOCNXCL,
                    698:        TIOCFLUSH,TIOCSETC, TIOCGETC, TIOCREMOTE,TIOCMGET,
                    699:        TIOCMBIC, TIOCMBIS, TIOCMSET, TIOCSTART,TIOCSTOP,
                    700:        TIOCPKT,  TIOCNOTTY,TIOCSTI,  TIOCOUTQ, TIOCGLTC,
                    701:        TIOCSLTC, TIOCSPGRP,TIOCGPGRP,TIOCCDTR, TIOCSDTR,
                    702:        TIOCCBRK, TIOCSBRK, TIOCLGET, TIOCLSET, TIOCLBIC,
                    703:        TIOCLBIS, 0
                    704: };
                    705: 
                    706: /*
                    707:  * Map an old style ioctl command to new.
                    708:  */
                    709: mapioctl(cmd)
                    710:        int cmd;
                    711: {
                    712:        register int *map, c;
                    713: 
                    714:        switch ((cmd >> 8) & 0xff) {
                    715: 
                    716:        case 'f':
                    717:                map = fctls;
                    718:                break;
                    719: 
                    720:        case 't':
                    721:                map = tctls;
                    722:                break;
                    723: 
                    724:        default:
                    725:                return (0);
                    726:        }
                    727:        while ((c = *map) && (c&0xff) < (cmd&0xff))
                    728:                map++;
                    729:        if (c && (c&0xff) == (cmd&0xff))
                    730:                return (c);
                    731:        return (0);
                    732: }
                    733: 
                    734: /*
                    735:  * emulate a read of n bytes on an old style directory
                    736:  */
                    737: oread(fd, buf, count)
                    738: int fd, count;
                    739: char *buf;
                    740: {
                    741:        struct fdflags *fp;
                    742:        struct direct *dp;
                    743:        DIR *dirp;
                    744:        struct odirect *odp;
                    745:        register int nleft = count;
                    746:        int dir_off;
                    747:        int i;
                    748: 
                    749:        fp = &fdflags[fd];
                    750:        dirp = fp->fd_dirp;
                    751:        odp = &fp->fd_od;
                    752:        if (dirp == NULL)
                    753:                return(-1);
                    754:        dir_off = fp->fd_offset % ODSIZE;
                    755:        if (dir_off) {
                    756:                i = ODSIZE - dir_off;
                    757:                if (nleft < i)
                    758:                        i = nleft;
                    759:                bcopy((caddr_t)odp + dir_off, buf, i);
                    760:                fp->fd_offset += i;
                    761:                if (i == nleft)
                    762:                        return(i);
                    763:                buf += i;
                    764:                nleft -= i;
                    765:        }
                    766:        while (nleft >= ODSIZE) {
                    767:                if ((dp = readdir(dirp)) == NULL)
                    768:                        return(count - nleft);
                    769:                odp->od_ino = dp->d_ino;
                    770:                strncpy(odp->od_name, dp->d_name, 14);
                    771:                bcopy((caddr_t)odp, buf, ODSIZE);
                    772:                fp->fd_offset += ODSIZE;
                    773:                buf += ODSIZE;
                    774:                nleft -= ODSIZE;
                    775:        }
                    776:        if (nleft > 0) {
                    777:                if ((dp = readdir(dirp)) == NULL)
                    778:                        return(count - nleft);
                    779:                odp->od_ino = dp->d_ino;
                    780:                strncpy(odp->od_name, dp->d_name, 14);
                    781:                bcopy((caddr_t)odp, buf, nleft);
                    782:                fp->fd_offset += nleft;
                    783:                /* nleft = 0; */
                    784:        }
                    785:        return(count);
                    786: }
                    787: 
                    788: /*
                    789:  * emulate the lseek system call
                    790:  */
                    791: off_t
                    792: olseek(fd, n, whence)
                    793: int fd, whence;
                    794: off_t n;
                    795: {
                    796:        struct fdflags *fp;
                    797:        char buf[512];
                    798:        off_t newpos;
                    799:        int i, j;
                    800: 
                    801:        if ((unsigned)fd >= NFILES)
                    802:                return(-1);
                    803:        fp = &fdflags[fd];
                    804:        /*
                    805:         * the system can handle everything
                    806:         * except directory files
                    807:         */
                    808:        if (fp->fd_dirp == NULL)
                    809:                return(lseek(fd, n, whence));
                    810:        switch (whence) {
                    811:        case 0:
                    812:                newpos = n;
                    813:                break;
                    814:        case 1:
                    815:                newpos = fp->fd_offset + n;
                    816:                break;
                    817:        case 2:         /* not yet implemented */
                    818:        default:
                    819:                return(-1);
                    820:        }
                    821:        if (newpos < 0)
                    822:                return(-1);
                    823:        if (newpos < fp->fd_offset) {
                    824:                rewinddir(fdflags[fd].fd_dirp);
                    825:                fp->fd_offset = 0;
                    826:        }
                    827:        i = newpos - fp->fd_offset;
                    828:        while (i > 0) {
                    829:                j = i < 512 ? i : 512;
                    830:                if (oread(fd, buf, j) != j)
                    831:                        break;
                    832:                i -= j;
                    833:        }
                    834:        return(fp->fd_offset);
                    835: }

unix.superglobalmegacorp.com

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