1*14311Ssam static char sccsid[] = "@(#)unixtraps.c 4.2 83/07/31"; 2*14311Ssam 3*14311Ssam /* 4*14311Ssam * Function to execute version 6 and version 7 UNIX system calls from 5*14311Ssam * compatability mode on UNIX-32V. 66809Srrh * Art Wetzel August 1979 76809Srrh */ 8*14311Ssam 96809Srrh #include <stdio.h> 106809Srrh #include <signal.h> 116809Srrh #include <sys/types.h> 126809Srrh #include <sys/stat.h> 13*14311Ssam #include <sys/ioctl.h> 14*14311Ssam #include <sys/time.h> 156809Srrh #ifdef V6UNIX 166809Srrh #ifdef TRACE 176809Srrh #define RTSNAME "/../../../../usr/local/v6trc" 186809Srrh #else 196809Srrh #define RTSNAME "/../../../../usr/local/v6run" 206809Srrh #endif 216809Srrh #include "unix6sys.h" 226809Srrh #ifdef TRACE 236809Srrh #include "unix6sysn.h" 246809Srrh #endif 256809Srrh #endif 266809Srrh #ifdef V7UNIX 276809Srrh #ifdef TRACE 286809Srrh #define RTSNAME "/../../../../usr/local/v7trc" 296809Srrh #else 306809Srrh #define RTSNAME "/../../../../usr/local/v7run" 316809Srrh #endif 326809Srrh #include "unix7sys.h" 336809Srrh #ifdef TRACE 346809Srrh #include "unix7sysn.h" 356809Srrh #endif 366809Srrh #endif 376809Srrh #include "defs.h" 386809Srrh #define CARRY 1 396809Srrh #define MAXSARGS 25 406809Srrh #ifdef V6UNIX 416809Srrh #define ARGVLEN 512 426809Srrh #define ENVLEN 0 436809Srrh #endif 446809Srrh #ifdef V7UNIX 456809Srrh #define ARGVLEN 5120 466809Srrh #define ENVLEN 1000 476809Srrh #endif 486809Srrh char argvs[ARGVLEN+ENVLEN]; 496809Srrh int args[MAXSARGS]; 50*14311Ssam 516809Srrh /* 32v type stat structure */ 526809Srrh extern struct stat stat32v; 53*14311Ssam 546809Srrh /* place for times data so we can reverse the longs */ 556809Srrh struct timebuf { 566809Srrh long t1; 576809Srrh long t2; 586809Srrh long t3; 596809Srrh long t4; 606809Srrh } timebuf; 61*14311Ssam 626809Srrh /* place for pipe file descriptors */ 636809Srrh int pipes[2]; 64*14311Ssam 656809Srrh /* wait status */ 666809Srrh int wstatus; 67*14311Ssam 686809Srrh #ifdef V6UNIX 696809Srrh /* version 6 style stat structure */ 706809Srrh struct v6nod { 716809Srrh dev_t majmin; 726809Srrh ino_t inumber; 736809Srrh unsigned short flags; 746809Srrh unsigned char nlinks; 756809Srrh unsigned char uid; 766809Srrh unsigned char gid; 776809Srrh unsigned char size0; 786809Srrh unsigned short size1; 796809Srrh unsigned short addr[8]; 806809Srrh long actime; 816809Srrh long modtime; 826809Srrh } *v6stat; 836809Srrh #endif 84*14311Ssam 85*14311Ssam #ifdef V7UNIX 86*14311Ssam /* version 7 style stat structure */ 87*14311Ssam struct v7stat { 88*14311Ssam dev_t v7st_dev; 89*14311Ssam u_short v7st_ino; 90*14311Ssam u_short v7st_mode; 91*14311Ssam short v7st_nlink; 92*14311Ssam short v7st_uid; 93*14311Ssam short v7st_gid; 94*14311Ssam dev_t v7st_rdev; 95*14311Ssam int v7st_size; 96*14311Ssam int v7st_atime; 97*14311Ssam int v7st_mtime; 98*14311Ssam int v7st_ctime; 99*14311Ssam } statv7; 100*14311Ssam 101*14311Ssam struct timeb { 102*14311Ssam time_t time; 103*14311Ssam u_short millitm; 104*14311Ssam short timezone; 105*14311Ssam short dstflag; 106*14311Ssam } timeb; 107*14311Ssam #endif 108*14311Ssam 1096809Srrh /* do the trap stuff for the trap with code */ 110*14311Ssam dotrap(code) 111*14311Ssam int code; 112*14311Ssam { 1136809Srrh register unsigned short *argp, *savp, *savep; 1146809Srrh register int i, j, indirflg; 1156809Srrh register char *avp, *oavp; 1166809Srrh extern sigcatch(); 1176809Srrh extern errno; 118*14311Ssam 1196809Srrh /* clear out condition codes of psl */ 1206809Srrh psl &= ~017; 1216809Srrh /* special case of indirect sys call */ 122*14311Ssam if (code == 0) { 1236809Srrh /* remember this was indirect */ 1246809Srrh indirflg = 1; 1256809Srrh /* point to args */ 1266809Srrh argp = (unsigned short *)*(pc++); 1276809Srrh /* code for indirect sys call */ 1286809Srrh code = *argp++; 1296809Srrh /* is it legit */ 130*14311Ssam if (code>>8 != TRAPS) { 1316809Srrh fprintf(stderr,"Bad indirect sys call at 0x%x\n",pc-2); 1326809Srrh pc++; 1336809Srrh /* set carry flag */ 1346809Srrh psl |= CARRY; 1356809Srrh regs[0] = -1; 1366809Srrh return(-1); 1376809Srrh } 1386809Srrh code &= 0377; 139*14311Ssam } else { 1406809Srrh /* remember this was not indirect */ 1416809Srrh indirflg = 0; 1426809Srrh /* point to args */ 1436809Srrh argp = pc; 1446809Srrh } 1456809Srrh /* check if code too high or bad sys code */ 146*14311Ssam if (code >= NSYSTRAPS || sysargs[code][0] == ILLSYS) { 1476809Srrh fprintf(stderr,"Unimplimented trap %d at 0x%x\n",code,argp); 1486809Srrh /* set carry bit */ 1496809Srrh psl |= CARRY; 1506809Srrh regs[0] = -1; 1516809Srrh return(-1); 1526809Srrh } 1536809Srrh /* copy args to known locations */ 1546809Srrh i=0; 155*14311Ssam for (j=0; j<sysargs[code][0]; j++) 156*14311Ssam args[i++] = regs[j]; 157*14311Ssam for (j=0; j<(sysargs[code][1]); j++) 158*14311Ssam args[i++] = *argp++; 1596809Srrh #ifdef TRACE 1606809Srrh fprintf(stderr,"pid %d ",getpid()); 161*14311Ssam if (indirflg) 162*14311Ssam fprintf(stderr,"indirect "); 163*14311Ssam fprintf(stderr, "%s (%d) from 0%o with %d args", 164*14311Ssam sysnames[code], code, pc-1, i); 165*14311Ssam for (j=0; j<i; j++) 1666809Srrh fprintf(stderr," 0%o",args[j]); 167*14311Ssam if (code==OPEN || code==STAT || code==CREAT || code==EXEC || 168*14311Ssam code==UNLNK || code==LINK || code==CHDIR || code==MKNOD) 1696809Srrh fprintf(stderr," (%s)",args[0]); 1706809Srrh #ifdef V7UNIX 171*14311Ssam if (code==EXECE) 1726809Srrh fprintf(stderr," (%s)",args[0]); 1736809Srrh #endif 174*14311Ssam if (code==LINK) 1756809Srrh fprintf(stderr," (%s)",args[1]); 1766809Srrh #endif 1776809Srrh /* go do whatever sys call it is */ 178*14311Ssam switch (code) { 179*14311Ssam case FORK: 1806809Srrh /* indirect forks return pids on both sides - must do here */ 1816809Srrh /* this is possibly a bug in 32V */ 1826809Srrh i = fork(); 1836809Srrh break; 184*14311Ssam 185*14311Ssam case WAIT: 1866809Srrh i = wait(&wstatus); 1876809Srrh args[0] = i; 1886809Srrh args[1] = wstatus; 1896809Srrh break; 190*14311Ssam 191*14311Ssam case EXEC: 1926809Srrh #ifdef V7UNIX 193*14311Ssam case EXECE: 1946809Srrh #endif 1956809Srrh /* 1966809Srrh * have to do a lot of junk here to fix up an argv 1976809Srrh * for execute since (1) the pdp-11 argv consists of 16 1986809Srrh * bit pointers and (2) the argv itself is in the 1996809Srrh * pdp-11 program space where it would get clobbered 2006809Srrh * when a new program is read in and before its 2016809Srrh * argv is set up. 2026809Srrh */ 2036809Srrh avp = &argvs[0]; 2046809Srrh savp = (unsigned short *)args[1]; 2056809Srrh #ifdef V6UNIX 206*14311Ssam for (i=1; args[i] = *savp++; i++) 207*14311Ssam if (args[i] == 0177777) 208*14311Ssam break; 2096809Srrh #ifdef TRACE 210*14311Ssam else 211*14311Ssam fprintf(stderr,"argv[%d]%s ",i-1,args[i]); 2126809Srrh #endif 2136809Srrh #endif 2146809Srrh #ifdef V7UNIX 2156809Srrh savep = (unsigned short *)args[2]; 216*14311Ssam for (i=1; args[i] = *savp++; i++) 2176809Srrh #ifdef TRACE 2186809Srrh fprintf(stderr,"argv[%d]%s ",i-1,args[i]); 2196809Srrh #else 2206809Srrh ; 2216809Srrh #endif 2226809Srrh #endif 223*14311Ssam if (stat(args[0], &stat32v)) { 2246809Srrh /* return error here if file does not exist */ 2256809Srrh #ifdef TRACE 2266809Srrh fprintf(stderr," does not exist\n"); 2276809Srrh #endif 2286809Srrh i = -1; 2296809Srrh break; 2306809Srrh } 2316809Srrh /* must have execute permission */ 232*14311Ssam if (stat32v.st_mode & (S_IEXEC>>6)) 233*14311Ssam goto experm; 234*14311Ssam if (stat32v.st_mode & (S_IEXEC>>3)) { 235*14311Ssam if (stat32v.st_gid == getegid()) 236*14311Ssam goto experm; 237*14311Ssam if (geteuid() == 0) 238*14311Ssam goto experm; 2396809Srrh } 240*14311Ssam if (stat32v.st_mode & S_IEXEC) { 241*14311Ssam if (stat32v.st_uid == geteuid()) 242*14311Ssam goto experm; 243*14311Ssam if (geteuid() == 0) 244*14311Ssam goto experm; 2456809Srrh } 2466809Srrh /* return failure if no exec permision allowed */ 2476809Srrh i = -1; 2486809Srrh experm: 2496809Srrh /* can't exec a directory */ 250*14311Ssam if ((stat32v.st_mode&S_IFMT) == S_IFDIR) 2516809Srrh i = -1; 252*14311Ssam if (i == -1) 253*14311Ssam break; 2546809Srrh args[i] = 0; 255*14311Ssam for (j=0; j<i; j++) { 2566809Srrh oavp = (char *)args[j]; 2576809Srrh args[j] = (int)avp; 258*14311Ssam while (*avp++ = *oavp++) 259*14311Ssam ; 2606809Srrh } 2616809Srrh #ifdef V7UNIX 262*14311Ssam if (code == EXECE) { 263*14311Ssam for (j = ++i; args[j] = *savep++; j++) 264*14311Ssam ; 265*14311Ssam for ( ; j > i; j--) { 2666809Srrh oavp = (char *)args[j]; 2676809Srrh args[j] = (int)avp; 268*14311Ssam while (*avp++ = *oavp++) 269*14311Ssam ; 2706809Srrh } 2716809Srrh } 2726809Srrh #endif 2736809Srrh /* SETUID and SETGID files must be started with a fresh RTS */ 274*14311Ssam if (stat32v.st_mode & S_ISGID || stat32v.st_mode & S_ISUID) { 2756809Srrh /* should add a check here for good magic # in header */ 2766809Srrh args[1] = args[0]; 2776809Srrh args[0] = (int)RTSNAME; 2786809Srrh #ifdef TRACE 2796809Srrh fprintf(stderr," SETUID-GID"); 2806809Srrh #endif 281*14311Ssam if (args[i]) 2826809Srrh i = execve(args[0], &args[0], &args[i]); 2836809Srrh else 2846809Srrh i = execv(args[0], &args[0]); 2856809Srrh fprintf(stderr,"can't exec %s\n",RTSNAME); 2866809Srrh break; 2876809Srrh } 2886809Srrh i = execute(args[0], &args[1], &args[i]); 2896809Srrh /* shouldn't get here if exec works */ 2906809Srrh break; 291*14311Ssam 292*14311Ssam case SEEK: 2936809Srrh #ifdef V6UNIX 2946809Srrh /* fix up negative offsets */ 295*14311Ssam if (args[2] != 0 && args[2] != 3) 296*14311Ssam if (args[1] >= 32768) 297*14311Ssam args[1] -= 65536; 298*14311Ssam if (args[2] <= 2) 2996809Srrh i = lseek(args[0], args[1], args[2]); 3006809Srrh else 3016809Srrh i = lseek(args[0], args[1]*512, args[2]-3); 302*14311Ssam if (i != -1) 303*14311Ssam i = 0; 3046809Srrh #endif 3056809Srrh #ifdef V7UNIX 3066809Srrh i = lseek(args[0], (args[1]<<16)|(args[2]&0177777), args[3]); 3076809Srrh #endif 3086809Srrh break; 309*14311Ssam 3106809Srrh #ifdef V6UNIX 311*14311Ssam case MKNOD: 3126809Srrh /* version 6 uses allocated bit which means regular file here */ 313*14311Ssam if (args[1] & S_IFBLK) 3146809Srrh args[1] &= ~S_IFREG; 3156809Srrh i = mknod(args[0], args[1], args[2]); 3166809Srrh break; 3176809Srrh #endif 318*14311Ssam 319*14311Ssam case PIPE: 3206809Srrh i = pipe(pipes); 3216809Srrh args[0] = pipes[0]; 3226809Srrh args[1] = pipes[1]; 3236809Srrh break; 324*14311Ssam 3256809Srrh #ifdef V6UNIX 326*14311Ssam case TELL: 3276809Srrh i = lseek(args[0], 0L, 1); 3286809Srrh break; 329*14311Ssam 330*14311Ssam case STTY: 331*14311Ssam i = stty(args[0], args[1]); 332*14311Ssam break; 333*14311Ssam 334*14311Ssam case GTTY: 335*14311Ssam i = gtty(args[0], args[1]); 336*14311Ssam break; 3376809Srrh #endif 338*14311Ssam 339*14311Ssam case STAT: 340*14311Ssam i = stat(args[0], &stat32v); 341*14311Ssam goto allstat; 342*14311Ssam 343*14311Ssam case FSTAT: 3446809Srrh /* do the syscall to a local stat buffer */ 345*14311Ssam i = fstat(args[0], &stat32v); 346*14311Ssam 347*14311Ssam allstat: 3486809Srrh /* reverse the longs */ 3496809Srrh stat32v.st_size = longrev(stat32v.st_size); 3506809Srrh stat32v.st_atime = longrev(stat32v.st_atime); 3516809Srrh stat32v.st_mtime = longrev(stat32v.st_mtime); 3526809Srrh stat32v.st_ctime = longrev(stat32v.st_ctime); 3536809Srrh #ifdef V7UNIX 354*14311Ssam statv7.v7st_dev = stat32v.st_dev; 355*14311Ssam statv7.v7st_ino = stat32v.st_ino; 356*14311Ssam statv7.v7st_mode = stat32v.st_mode; 357*14311Ssam statv7.v7st_nlink = stat32v.st_nlink; 358*14311Ssam statv7.v7st_uid = stat32v.st_uid; 359*14311Ssam statv7.v7st_gid = stat32v.st_gid; 360*14311Ssam statv7.v7st_rdev = stat32v.st_rdev; 361*14311Ssam statv7.v7st_size = stat32v.st_size; 362*14311Ssam statv7.v7st_atime = stat32v.st_atime; 363*14311Ssam statv7.v7st_mtime = stat32v.st_mtime; 364*14311Ssam statv7.v7st_ctime = stat32v.st_ctime; 3656809Srrh /* copy out otherwise unchanged stat buffer */ 3666809Srrh /* in two pieces with st_size as the breaking point */ 3676809Srrh /* note that st_rdev is a short but due to alingnmemt */ 3686809Srrh /* problems the rest of the structure is out of sync */ 369*14311Ssam j = (int)((char *)(&statv7.v7st_size) - 370*14311Ssam (char *)(&statv7.v7st_dev)); 371*14311Ssam bcopy(&statv7, args[1], j); 372*14311Ssam bcopy(&statv7.v7st_size, args[1]+j-2, sizeof(struct v7stat)-j); 3736809Srrh #endif 3746809Srrh #ifdef V6UNIX 3756809Srrh /* point to user area as v6stat structure */ 3766809Srrh v6stat = (struct v6nod *)args[1]; 3776809Srrh /* copy out piece by piece */ 3786809Srrh v6stat->majmin = stat32v.st_dev; 3796809Srrh v6stat->inumber = stat32v.st_ino; 3806809Srrh v6stat->flags = stat32v.st_mode; 3816809Srrh v6stat->nlinks = (unsigned char)stat32v.st_nlink; 3826809Srrh v6stat->uid = (unsigned char)stat32v.st_uid; 3836809Srrh v6stat->gid = (unsigned char)stat32v.st_gid; 3846809Srrh /* note size already reversed */ 3856809Srrh v6stat->size0 = (unsigned char)(stat32v.st_size & 0377); 3866809Srrh v6stat->size1 = (unsigned short)(stat32v.st_size>>16); 3876809Srrh v6stat->actime = stat32v.st_atime; 3886809Srrh v6stat->modtime = stat32v.st_mtime; 3896809Srrh /* patch up flags */ 3906809Srrh /* for now just set 100000 bit if not a plain file */ 391*14311Ssam if (v6stat->flags & 060000) 3926809Srrh v6stat->flags |= 0100000; 3936809Srrh #endif 3946809Srrh break; 395*14311Ssam 396*14311Ssam case TIMES: 3976809Srrh i = times(&timebuf); 3986809Srrh timebuf.t2 = longrev(timebuf.t2) + timebuf.t1; 3996809Srrh timebuf.t3 = longrev(timebuf.t3); 4006809Srrh timebuf.t4 = longrev(timebuf.t4); 4016809Srrh bcopy(&timebuf.t2,args[0],sizeof(struct timebuf)-sizeof(long)); 4026809Srrh break; 403*14311Ssam 4046809Srrh #ifdef V6UNIX 405*14311Ssam case SLEEP: 4066809Srrh /* do a sleep function - what about pwb which has alarm? */ 4076809Srrh sleep(args[0]); 4086809Srrh break; 4096809Srrh #endif 410*14311Ssam 411*14311Ssam case GETUID: 4126809Srrh args[0] = getuid(); 4136809Srrh args[1] = geteuid(); 4146809Srrh #ifdef V6UNIX 415*14311Ssam i = args[1]<<8 | (args[0] & 0377); 4166809Srrh #endif 4176809Srrh break; 418*14311Ssam 419*14311Ssam case GETGID: 4206809Srrh args[0] = getgid(); 4216809Srrh args[1] = getegid(); 4226809Srrh #ifdef V6UNIX 423*14311Ssam i = args[1]<<8 | (args[0] & 0377); 4246809Srrh #endif 4256809Srrh break; 426*14311Ssam 427*14311Ssam /* uids and gids are 8 bits in version 6 */ 428*14311Ssam case SETUID: 429*14311Ssam case SETGID: 4306809Srrh #ifdef V6UNIX 431*14311Ssam args[0] &= 0377; 432*14311Ssam #endif 433*14311Ssam if (code == SETUID) 434*14311Ssam i = setuid(args[0]); 435*14311Ssam else 436*14311Ssam i = setgid(args[0]); 4376809Srrh break; 438*14311Ssam 439*14311Ssam case SIG: 4406809Srrh /* if it is a good signal code */ 441*14311Ssam if (args[0] <= NSIG) { 4426809Srrh /* get the current signal value */ 4436809Srrh i = sigvals[args[0]]; 4446809Srrh /* reset the signal to the new value */ 4456809Srrh sigvals[args[0]] = args[1]; 4466809Srrh /* actually do signal except don't reset SIGILL */ 447*14311Ssam if (args[0] != SIGILL) { 448*14311Ssam if (args[1] == (int)SIG_DFL || 449*14311Ssam args[1] & (int)SIG_IGN) { 450*14311Ssam if ((int)signal(args[0],args[1]) == -1) 4516809Srrh i = -1; 4526809Srrh } else { 453*14311Ssam if ((int)signal(args[0],sigcatch) == -1) 4546809Srrh i = -1; 4556809Srrh } 4566809Srrh } 457*14311Ssam } else 458*14311Ssam i = -1; 4596809Srrh break; 460*14311Ssam 461*14311Ssam case BRK: 4626809Srrh /* brk is successful unless we run over the stack */ 463*14311Ssam /* NB: this assumes register usage which need not be used */ 4646809Srrh i = 0; 465*14311Ssam if (args[0] >= regs[6]) 466*14311Ssam i = -1; 4676809Srrh break; 468*14311Ssam 469*14311Ssam /* 470*14311Ssam * the next bunch are to cope with sys calls removed from 4.2 471*14311Ssam */ 472*14311Ssam case TIME: 473*14311Ssam i = time(0); 474*14311Ssam break; 475*14311Ssam 476*14311Ssam case STIME: { 477*14311Ssam struct timeval tv; 478*14311Ssam 479*14311Ssam tv.tv_usec = 0; 480*14311Ssam tv.tv_sec = (args[0] & 0xffff) | ((args[1] & 0xffff) << 16); 481*14311Ssam i = settimeofday(&tv); 482*14311Ssam break; 483*14311Ssam } 484*14311Ssam 485*14311Ssam case NICE: 486*14311Ssam i = nice(args[0]); 487*14311Ssam break; 488*14311Ssam 489*14311Ssam #ifdef V7UNIX 490*14311Ssam case ALARM: 491*14311Ssam i = alarm(args[0]); 492*14311Ssam break; 493*14311Ssam 494*14311Ssam case PAUSE: 495*14311Ssam i = pause(); 496*14311Ssam break; 497*14311Ssam 498*14311Ssam case UTIME: 499*14311Ssam i = utime(args[0], args[1]); 500*14311Ssam break; 501*14311Ssam 502*14311Ssam case FTIME: 503*14311Ssam i = ftime(&timeb); 504*14311Ssam timeb.time = longrev(timeb.time); 505*14311Ssam bcopy(&timeb, args[0], sizeof timeb - 2); 506*14311Ssam break; 507*14311Ssam 508*14311Ssam case IOCTL: 509*14311Ssam args[1] = mapioctl(args[1]); 510*14311Ssam if (args[1] == 0) 511*14311Ssam i = -1; 512*14311Ssam else 513*14311Ssam i = ioctl(args[0], args[1], args[2]); 514*14311Ssam break; 515*14311Ssam #endif 516*14311Ssam 5176809Srrh #ifdef V6UNIX 518*14311Ssam case PWBSYS: 5196809Srrh /* ignore pwbsys for now */ 520*14311Ssam switch (args[2]) { 521*14311Ssam case UNAME: 5226809Srrh #ifdef TRACE 5236809Srrh fprintf(stderr,"UNAME with %d %d\n",args[0],args[1]); 5246809Srrh #endif 5256809Srrh strcpy(args[0],"pwbname"); 5266809Srrh i = 0; 5276809Srrh break; 528*14311Ssam 529*14311Ssam case UDATA: 5306809Srrh #ifdef TRACE 5316809Srrh fprintf(stderr,"UDATA with %d %d\n",args[0],args[1]); 5326809Srrh #endif 5336809Srrh i = 0; 5346809Srrh break; 535*14311Ssam 536*14311Ssam case USTAT: 5376809Srrh fprintf(stderr,"USTAT with %d %d\n",args[0],args[1]); 5386809Srrh i = 0; 5396809Srrh break; 540*14311Ssam 541*14311Ssam case UTIME: 5426809Srrh fprintf(stderr,"UTIME with %d %d\n",args[0],args[1]); 5436809Srrh i = 0; 5446809Srrh break; 5456809Srrh default: 5466809Srrh fprintf(stderr,"bad PWBSYS %d\n",args[3]); 5476809Srrh i = -1; 5486809Srrh break; 5496809Srrh } 5506809Srrh break; 5516809Srrh #endif 552*14311Ssam 5536809Srrh default: 5546809Srrh /* 5556809Srrh * Many sys calls are easily done here since most 5566809Srrh * system call codes are the same on version 6 and 7 UNIX 5576809Srrh * as they are here. 5586809Srrh */ 5596809Srrh i = syscall(code,args[0],args[1],args[2],args[3],args[4]); 5606809Srrh #ifdef V6UNIX 561*14311Ssam /* allow read write access to created files for (IDIS v6 mod) */ 562*14311Ssam if (code==CREAT) { 5636809Srrh /* get actual file mode after create */ 5646809Srrh fstat(i, &stat32v); 5656809Srrh close(i); 5666809Srrh /* ensure read/write access to owner */ 5676809Srrh chmod(args[0], 0644); 5686809Srrh i = open(args[0], 2); 5696809Srrh /* change mode back the way it was */ 5706809Srrh chmod(args[0], stat32v.st_mode); 5716809Srrh } 5726809Srrh #endif 5736809Srrh break; 5746809Srrh } 5756809Srrh #ifdef TRACE 5766809Srrh fprintf(stderr," sys val -> 0%o\n",i); 5776809Srrh #endif 5786809Srrh /* set carry bit if sys error */ 579*14311Ssam if (i == -1) 5806809Srrh psl |= CARRY; 5816809Srrh /* if not an indirect sys call, adjust the pc */ 582*14311Ssam if (indirflg == 0) 5836809Srrh pc = argp; 5846809Srrh /* do alternate return on one side of fork */ 585*14311Ssam if (code == FORK && i != 0) 5866809Srrh pc++; 5876809Srrh /* do the various return value formats */ 588*14311Ssam switch (sysargs[code][2]) { 589*14311Ssam case NORMRET: 5906809Srrh /* normal case only one return value in r0 */ 5916809Srrh regs[0] = i; 5926809Srrh break; 593*14311Ssam case LONGRET: 5946809Srrh /* return a long in r0 - r1 as in time */ 5956809Srrh regs[1] = i; 5966809Srrh regs[0] = i >> 16; 5976809Srrh break; 598*14311Ssam case TWORET: 5996809Srrh /* return two ints in r0 - r1 as in pipe */ 600*14311Ssam if (i == -1) 6016809Srrh regs[0] = i; 6026809Srrh else { 6036809Srrh regs[1] = args[1]; 6046809Srrh regs[0] = args[0]; 6056809Srrh } 6066809Srrh break; 6076809Srrh } 608*14311Ssam if (i== -1) 6096809Srrh regs[0] = errno; 6106809Srrh } 611*14311Ssam 612*14311Ssam long 613*14311Ssam longrev(l) 614*14311Ssam long l; 615*14311Ssam { 6166809Srrh /* function to reverse the halves of a long */ 6176809Srrh union { 6186809Srrh long lng; 6196809Srrh short s[2]; 6206809Srrh } u; 6216809Srrh register short t; 6226809Srrh u.lng = l; 6236809Srrh t = u.s[0]; 6246809Srrh u.s[0] = u.s[1]; 6256809Srrh u.s[1] = t; 6266809Srrh return(u.lng); 6276809Srrh } 628*14311Ssam 629*14311Ssam /* 630*14311Ssam * Note: these tables are sorted by 631*14311Ssam * ioctl "code" (in ascending order). 632*14311Ssam */ 633*14311Ssam int fctls[] = { FIOCLEX, FIONCLEX, FIOASYNC, FIONBIO, FIONREAD, 0 }; 634*14311Ssam int tctls[] = { 635*14311Ssam TIOCGETD, TIOCSETD, TIOCHPCL, TIOCMODG, TIOCMODS, 636*14311Ssam TIOCGETP, TIOCSETP, TIOCSETN, TIOCEXCL, TIOCNXCL, 637*14311Ssam TIOCFLUSH,TIOCSETC, TIOCGETC, TIOCREMOTE,TIOCMGET, 638*14311Ssam TIOCMBIC, TIOCMBIS, TIOCMSET, TIOCSTART,TIOCSTOP, 639*14311Ssam TIOCPKT, TIOCNOTTY,TIOCSTI, TIOCOUTQ, TIOCGLTC, 640*14311Ssam TIOCSLTC, TIOCSPGRP,TIOCGPGRP,TIOCCDTR, TIOCSDTR, 641*14311Ssam TIOCCBRK, TIOCSBRK, TIOCLGET, TIOCLSET, TIOCLBIC, 642*14311Ssam TIOCLBIS, 0 643*14311Ssam }; 644*14311Ssam 645*14311Ssam /* 646*14311Ssam * Map an old style ioctl command to new. 647*14311Ssam */ 648*14311Ssam mapioctl(cmd) 649*14311Ssam int cmd; 650*14311Ssam { 651*14311Ssam register int *map, c; 652*14311Ssam 653*14311Ssam switch ((cmd >> 8) & 0xff) { 654*14311Ssam 655*14311Ssam case 'f': 656*14311Ssam map = fctls; 657*14311Ssam break; 658*14311Ssam 659*14311Ssam case 't': 660*14311Ssam map = tctls; 661*14311Ssam break; 662*14311Ssam 663*14311Ssam default: 664*14311Ssam return (0); 665*14311Ssam } 666*14311Ssam while ((c = *map) && (c&0xff) < (cmd&0xff)) 667*14311Ssam map++; 668*14311Ssam if (c && (c&0xff) == (cmd&0xff)) 669*14311Ssam return (c); 670*14311Ssam return (0); 671*14311Ssam } 672