Annotation of 43BSDReno/old/games.vax/compat/unixtraps.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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