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