[comp.os.minix] V1.3 posting #16 - four important new files

ast@cs.vu.nl (Andy Tanenbaum) (06/28/88)

Here are four important files:

  - commands/fix.c  (slightly immune to Bitnet)
  - commands/stty.c (handles baudrate for RS232)
  - commands/cdiff.c (is included in 1.3)
  - lib/ioctl.c     (needed by new stty.c)

Please install all of these.

Andy Tanenbaum (ast@cs.vu.nl)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'fix.c'
sed 's/^X//' > 'fix.c' << '+ END-OF-FILE ''fix.c'
X/* fix file difflist - update file from difflist     Author: Erik Baalbergen */
X
X
X/* Notes:
X   * files old and old.patch are equal after the following commands
X	   diff old new > difflist
X	   patch old difflist > old.patch
X   * the diff output is assumed to be produced by my diff program.
X   * the difflist has the following form:
X	   difflist ::= chunk*
X	   chunk ::= append | delete | change ;
X	   append ::= n1 'a' n2 [',' n3]? '\n' ['> ' line '\n'](n3 - n2 + 1)
X	   delete ::= n1 [',' n2]? 'd' n3 '\n' ['< ' line '\n'](n2 - n1 + 1)
X	   change ::= n1 [',' n2]? 'c' n3 [',' n4]? '\n'
X		      ['< ' line '\n'](n2 - n1 + 1)
X		      '---\n'
X		      ['> ' line '\n'](n4 - n3 + 1)
X	   where
X	   - n[1234] is an unsigned integer
X	   - "[pat](expr)" means "(expr) occurences of pat"
X	   - "[pat]?" means "either pat or nothing"
X   * the information in the diff listing is checked against the file to which
X     it is applied; an error is printed if there is a conflict
X*/
X
X#include <stdio.h>
X
X#define IGNORE_WHITE_SPACE 	/* This makes it white space insensitive */
X
X#ifdef IGNORE_WHITE_SPACE
X#define strcmp strwcmp  
X#endif
X
Xextern char *fgets();
Xextern FILE *fopen();
X#define LINELEN	1024
X
Xchar *prog = 0,
X     *processing=0;
X
Xchar *
Xgetline(fp, b)
X	FILE *fp;
X	char *b;
X{
X	int slen;
X	if (fgets(b, LINELEN, fp) == NULL)
X		fatal("unexpected eof");
X
X	return b;
X}
X
X#define copy(str) printf("%s", str)
X
Xmain(argc, argv)
X	char **argv;
X{
X	char cmd, *fl, *fd, obuf[LINELEN], nbuf[LINELEN];
X	int o1, o2, n1, n2, here; 
X	FILE *fpf, *fpd;
X
X	prog = argv[0];
X	processing = argv[1];
X	if (argc != 3)
X		fatal("use: %s original-file diff-list-file", prog);
X	if ((fpf = fopen(argv[1], "r")) == NULL)
X		fatal("can't read %s", argv[1]);
X	if ((fpd = fopen(argv[2], "r")) == NULL)
X		fatal("can't read %s", argv[2]);
X	here = 0;
X	while (getcommand(fpd, &o1, &o2, &cmd, &n1, &n2)) {
X		while (here < o1 - 1) {
X			here++;
X			copy(getline(fpf, obuf));
X		}
X		switch (cmd) {
X		case 'c':
X		case 'd':
X			if (cmd == 'd' && n1 != n2)
X				fatal("delete count conflict");
X			while (o1 <= o2) {
X				fl = getline(fpf, obuf);
X				here++;
X				fd = getline(fpd, nbuf);
X				if (strncmp(fd, "<", 1))
X					fatal("illegal delete line");
X				if (strcmp(fl, fd + 2))
X					fatal("delete line conflict");
X				o1++;
X			}
X			if (cmd == 'd')
X				break;
X			if (strcmp(getline(fpd, nbuf), "---\n"))
X				fatal("illegal separator in chunk");
X			/*FALLTHROUGH*/
X		case 'a':
X			if (cmd == 'a') {
X				if (o1 != o2)
X					fatal("append count conflict");
X				copy(getline(fpf, obuf));
X				here++;
X			}
X			while (n1 <= n2) {
X				if (strncmp(getline(fpd, nbuf), ">", 1))
X					fatal("illegal append line");
X				copy(nbuf + 2);
X				n1++;
X			}
X			break;
X		}
X	}
X	while (fgets(obuf, LINELEN, fpf) != NULL)
X		copy(obuf);
X	exit(0);
X}
X
Xisdigit(c)
X	char c;
X{
X	return c >= '0' && c <= '9';
X}
X
Xchar *
Xrange(s, p1, p2)
X	char *s;
X	int *p1, *p2;
X{
X	register int v1 = 0, v2;
X
X	while (isdigit(*s))
X		v1 = 10 * v1 + *s++ - '0';
X	v2 = v1;
X	if (*s == ',') {
X		s++;
X		v2 = 0;
X		while (isdigit(*s))
X			v2 = 10 * v2 + *s++ - '0';
X	}
X	if ( v1 > v2)
X		fatal("illegal range");
X	*p1 = v1;
X	*p2 = v2;
X	return s;
X}
X
Xgetcommand(fp, o1, o2, pcmd, n1, n2)
X	FILE *fp;
X	int *o1, *o2, *n1, *n2;
X	char *pcmd;
X{
X	char buf[LINELEN];
X	register char *s;
X	char cmd;
X	
X	if ((s = fgets(buf, LINELEN, fp)) == NULL)
X		return 0;
X	s = range(s, o1, o2);
X	if ((cmd = *s++) != 'a' && cmd != 'c' && cmd != 'd')
X		fatal("illegal command");
X	s = range(s, n1, n2);
X	if (*s != '\n' && s[1] != '\0')
X		fatal("extra characters at end of command: %s", s);
X	*pcmd = cmd;
X	return 1;
X}
X
Xfatal(s, a)
X	char *s, *a;
X{
X	fprintf(stderr, "%s: processing: %s fatal: ", prog,processing);
X	fprintf(stderr, s, a);
X	fprintf(stderr, "\n");
X	exit(1);
X}
X
X#ifdef IGNORE_WHITE_SPACE
X
X/* This routine is a white space insensitive version of strcmp. 
X   It is needed for testing things which might have undergone
X   tab conversion or trailing space removal  
X   Bret Mckee June, 1988 */
X
Xint strwcmp(s1,s2)
Xchar *s1,*s2;
X{
X	char *x1=s1,*x2=s2;
X
X	/* remove leading white space */
X	while(whitespace(*s1))
X		s1++;
X	while(whitespace(*s2))
X		s2++;
X	do
X	{
X		while((*s1 == *s2) && *s1 && *s2)
X		{
X			s1++;
X			s2++;
X		}
X	   		 ; /* consume identical characters */
X		while(whitespace(*s1))
X			s1++;
X		while(whitespace(*s2))
X			s2++;
X	}	while (*s1 && *s2 && (*s1 == *s2));
X	if (*s1-*s2)
X		fprintf(stderr,"Failing for (%x)[%s]\n            (%x)[%s]\n",
X			(int)*s1,x1,(int)*s2,x2);
X	return(*s1-*s2);
X}
X
Xint whitespace(ch)
Xchar ch;
X{
X	switch(ch)
X	{
X		case ' ': 
X		case '\n':
X		case 0x0D:  
X		case '\t': return(1);
X		default:  return(0);
X	}
X}
X#endif
+ END-OF-FILE fix.c
chmod 'u=rw,g=,o=' 'fix.c'
set `wc -c 'fix.c'`
count=$1
case $count in
4592)	:;;
*)	echo 'Bad character count in ''fix.c' >&2
		echo 'Count should be 4592' >&2
esac
echo Extracting 'stty.c'
sed 's/^X//' > 'stty.c' << '+ END-OF-FILE ''stty.c'
X/* stty - set terminal mode  	Author: Andy Tanenbaum */
X
X#include <sgtty.h>
Xchar *on[] = {"tabs",  "cbreak",  "raw",  "-nl",  "echo"};
Xchar *off[]= {"-tabs", "", "", "nl", "-echo"};
Xint k;
X
Xstruct sgttyb args;
Xstruct tchars tch;
X
X#define STARTC	 021		/* CTRL-Q */
X#define STOPC	 023		/* CTRL-S */
X#define QUITC	 034		/* CTRL-\ */
X#define EOFC	 004		/* CTRL-D */
X#define DELC	0177		/* DEL */
X
X#define speed(s) args.sg_ispeed = s;  args.sg_ospeed = s
X#define clr1 args.sg_flags &= ~(BITS5 | BITS6 | BITS7 | BITS8)
X#define clr2 args.sg_flags &= ~(EVENP | ODDP)
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X
X  /* stty with no arguments just reports on current status. */
X  ioctl(0, TIOCGETP, &args);
X  ioctl(0, TIOCGETC, &tch);
X  if (argc == 1) {
X	report();
X	exit(0);
X  }
X
X  /* Process the options specified. */
X  k = 1;
X  while (k < argc) {
X	option(argv[k], k+1 < argc ? argv[k+1] : "");
X	k++;
X  }
X  ioctl(0, TIOCSETP, &args);
X  ioctl(0, TIOCSETC, &tch);
X  exit(0);
X}
X
X
X
Xreport()
X{
X  int mode;
X
X
X  mode = args.sg_flags;
X  pr(mode&XTABS, 0);
X  pr(mode&CBREAK, 1);
X  pr(mode&RAW, 2);
X  pr(mode&CRMOD,3);
X  pr(mode&ECHO,4);
X  prints("\nkill = "); 	prctl(args.sg_kill);
X  prints("\nerase = ");	prctl(args.sg_erase);
X  prints("\nint = "); 	prctl(tch.t_intrc);
X  prints("\nquit = "); 	prctl(tch.t_quitc);
X  prints("\n");
X}
X
Xpr(f, n)
Xint f,n;
X{
X  if (f)
X	prints("%s ",on[n]);
X  else
X	prints("%s ",off[n]);
X}
X
Xoption(opt, next)
Xchar *opt, *next;
X{
X  if (match(opt, "-tabs"))	{args.sg_flags &= ~XTABS; return;}
X  if (match(opt, "-odd"))	{args.sg_flags &= ~ODDP; return;}
X  if (match(opt, "-even"))	{args.sg_flags &= ~EVENP; return;}
X  if (match(opt, "-raw"))	{args.sg_flags &= ~RAW; return;}
X  if (match(opt, "-cbreak"))	{args.sg_flags &= ~CBREAK; return;}
X  if (match(opt, "-echo"))	{args.sg_flags &= ~ECHO; return;}
X  if (match(opt, "-nl"))	{args.sg_flags |= CRMOD; return;}
X
X  if (match(opt, "tabs"))	{args.sg_flags |= XTABS; return;}
X  if (match(opt, "even"))	{clr2; args.sg_flags |= EVENP; return;}
X  if (match(opt, "odd"))	{clr2; args.sg_flags |= ODDP; return;}
X  if (match(opt, "raw"))	{args.sg_flags |= RAW; return;}
X  if (match(opt, "cbreak"))	{args.sg_flags |= CBREAK; return;}
X  if (match(opt, "echo"))	{args.sg_flags |= ECHO; return;}
X  if (match(opt, "nl"))		{args.sg_flags &= ~CRMOD; return;}
X
X  if (match(opt, "kill"))	{args.sg_kill = *next; k++; return;}
X  if (match(opt, "erase"))	{args.sg_erase = *next; k++; return;}
X  if (match(opt, "int"))	{tch.t_intrc = *next; k++; return;}
X  if (match(opt, "quit"))	{tch.t_quitc = *next; k++; return;}
X
X  if (match(opt, "5"))		{clr1; args.sg_flags |= BITS5; return;}
X  if (match(opt, "6"))		{clr1; args.sg_flags |= BITS6; return;}
X  if (match(opt, "7"))		{clr1; args.sg_flags |= BITS7; return;}
X  if (match(opt, "8"))		{clr1; args.sg_flags |= BITS8; return;}
X
X  if (match(opt, "110"))	{speed(B110); return;}
X  if (match(opt, "300"))	{speed(B300); return;}
X  if (match(opt, "1200"))	{speed(B1200); return;}
X  if (match(opt, "2400"))	{speed(B2400); return;}
X  if (match(opt, "4800"))	{speed(B4800); return;}
X  if (match(opt, "9600"))	{speed(B9600); return;}
X
X  if (match(opt, "default"))	{
X	args.sg_flags = ECHO | CRMOD | XTABS | BITS8;
X	args.sg_ispeed = B1200;
X	args.sg_ospeed = B1200;
X	args.sg_kill = '@';
X	args.sg_erase = '\b';
X  	tch.t_intrc = DELC;
X  	tch.t_quitc = QUITC;
X  	tch.t_startc = STARTC;
X  	tch.t_stopc = STOPC;
X  	tch.t_eofc = EOFC;
X  	return;
X  }
X  	
X  std_err("unknown mode: ");
X  std_err(opt);
X  std_err("\n");
X
X}
X
Xint match(s1, s2)
Xchar *s1, *s2;
X{
X
X  while (1) {
X	if (*s1 == 0 && *s2 == 0) return(1);
X	if (*s1 == 0 || *s2 == 0) return(0);
X	if (*s1 != *s2) return(0);
X	s1++;
X	s2++;
X  }
X}
X
Xprctl(c)
Xchar c;
X{
X  if (c < ' ')
X	prints("^%c", 'A' + c - 1);
X  else if (c == 0177)
X	prints("DEL");
X  else
X	prints("%c", c);
X}
+ END-OF-FILE stty.c
chmod 'u=rw,g=r,o=r' 'stty.c'
set `wc -c 'stty.c'`
count=$1
case $count in
3780)	:;;
*)	echo 'Bad character count in ''stty.c' >&2
		echo 'Count should be 3780' >&2
esac
echo Extracting 'cdiff.c'
sed 's/^X//' > 'cdiff.c' << '+ END-OF-FILE ''cdiff.c'
X/* cdiff - context diff			Author: Larry Wall */
X
X/* cdiff - turns a regular diff into a new-style context diff
X *
X * Usage: cdiff file1 file2
X *
X * $Log:	cdiff.c,v $
X * Revision 1.1.1.2  87/06/04  11:21:43  lwall
X * Didn't do diffs with less than 3 lines of leading context.
X * 
X * Revision 1.1.1.1  87/06/03  11:52:25  lwall
X * Wasn't concatenating overlapping hunks right.
X * 
X * Revision 1.1  87/06/01  16:05:57  lwall
X * Initial revision
X * 
X */
Xstatic char rcsid[] = "$Header: cdiff.c,v 1.1.1.2 87/06/04 11:21:43 lwall Exp $";
X
X#define PATCHLEVEL 2
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <ctype.h>
X
Xchar buff[512];
X
XFILE *inputfp, *oldfp, *newfp;
X
Xint oldmin, oldmax, newmin, newmax;
Xint oldbeg, oldend, newbeg, newend;
Xint preoldmax, prenewmax;
Xint preoldbeg, preoldend, prenewbeg, prenewend;
Xint oldwanted, newwanted;
X
Xchar *oldhunk, *newhunk;
Xunsigned oldsize, oldalloc, newsize, newalloc;
X
Xvoid dumphunk();
Xchar *getold();
Xchar *getnew();
Xchar *malloc();
Xchar *realloc();
Xchar *fgets();
XFILE *popen();
X
X#define Nullfp (FILE*)0
X#define Nullch (char*)0
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X    char *old, *new;
X    int context = 3;
X    struct stat statbuf;
X    register char *s;
X    char op;
X    char *newmark, *oldmark;
X    int len;
X    char *line;
X    int i;
X
X    oldalloc = 512;
X    oldhunk = malloc(oldalloc);
X    newalloc = 512;
X    newhunk = malloc(newalloc);
X
X    for (argc--,argv++; argc; argc--,argv++) {
X	if (argv[0][0] != '-')
X	    break;
X	if (argv[0][1] == 'v') {
X	    printf("%s\n	Patch level: %d\n",rcsid,PATCHLEVEL);
X	    exit(0);
X	}
X	if (argv[0][1] == 'c')
X	    context = atoi(argv[0]+2);
X    }
X
X    if (argc != 2) {
X	fprintf(stderr,"Usage: cdiff old new\n");
X	exit(1);
X    }
X
X    old = argv[0];
X    new = argv[1];
X
X    sprintf(buff,"diff %s %s", old, new);
X    inputfp = popen(buff, "r");
X    if (!inputfp) {
X	fprintf(stderr, "Can't execute diff %s %s\n", old, new);
X	exit(1);
X    }
X
X    oldfp = fopen(old,"r");
X    if (!oldfp) {
X	fprintf(stderr, "Can't open %s\n", old);
X	exit(1);
X    }
X    newfp = fopen(new,"r");
X    if (!newfp) {
X	fprintf(stderr, "Can't open %s\n", new);
X	exit(1);
X    }
X
X    fstat(fileno(oldfp),&statbuf);
X    printf("*** %s\t%s", old, ctime(&statbuf.st_mtime));
X    fstat(fileno(newfp),&statbuf);
X    printf("--- %s\t%s", new, ctime(&statbuf.st_mtime));
X
X    preoldend = -1000;
X
X    while (fgets(buff, sizeof buff, inputfp) != Nullch) {
X	if (isdigit(*buff)) {
X	    oldmin = atoi(buff);
X	    for (s = buff; isdigit(*s); s++) ;
X	    if (*s == ',') {
X		s++;
X		oldmax = atoi(s);
X		for ( ; isdigit(*s); s++) ;
X	    }
X	    else {
X		oldmax = oldmin;
X	    }
X	    if (*s != 'a' && *s != 'd' && *s != 'c') {
X		fprintf(stderr, "Unparseable input: %s", s);
X		exit(1);
X	    }
X	    op = *s;
X	    s++;
X	    newmin = atoi(s);
X	    for ( ; isdigit(*s); s++) ;
X	    if (*s == ',') {
X		s++;
X		newmax = atoi(s);
X		for ( ; isdigit(*s); s++) ;
X	    }
X	    else {
X		newmax = newmin;
X	    }
X	    if (*s != '\n' && *s != ' ') {
X		fprintf(stderr, "Unparseable input: %s", s);
X		exit(1);
X	    }
X
X	    newmark = oldmark = "! ";
X	    if (op == 'a') {
X		oldmin++;
X		newmark = "+ ";
X	    }
X	    if (op == 'd') {
X		newmin++;
X		oldmark = "- ";
X	    }
X
X	    oldbeg = oldmin - context;
X	    oldend = oldmax + context;
X	    if (oldbeg < 1)
X		oldbeg = 1;
X	    newbeg = newmin - context;
X	    newend = newmax + context;
X	    if (newbeg < 1)
X		newbeg = 1;
X
X	    if (preoldend < oldbeg - 1) {
X		if (preoldend >= 0) {
X		    dumphunk();
X		}
X		preoldbeg = oldbeg;
X		prenewbeg = newbeg;
X		oldwanted = newwanted = 0;
X		oldsize = newsize = 0;
X	    } else {	/* we want to append to previous hunk */
X		oldbeg = preoldmax + 1;
X		newbeg = prenewmax + 1;
X	    }
X
X	    for (i = oldbeg; i <= oldmax; i++) {
X		line = getold(i);
X		if (!*line) {
X		    oldend = oldmax = i - 1;
X		    break;
X		}
X		len = strlen(line) + 2;
X		if (oldsize + len + 1 >= oldalloc) {
X		    oldalloc *= 2;
X		    oldhunk = realloc(oldhunk, oldalloc);
X		}
X		if (i >= oldmin) {
X		    strcpy(oldhunk+oldsize, oldmark);
X		    oldwanted++;
X		}
X		else {
X		    strcpy(oldhunk+oldsize, "  ");
X		}
X		strcpy(oldhunk+oldsize+2,line);
X		oldsize += len;
X	    }
X	    preoldmax = oldmax;
X	    preoldend = oldend;
X
X	    for (i = newbeg; i <= newmax; i++) {
X		line = getnew(i);
X		if (!*line) {
X		    newend = newmax = i - 1;
X		    break;
X		}
X		len = strlen(line) + 2;
X		if (newsize + len + 1 >= newalloc) {
X		    newalloc *= 2;
X		    newhunk = realloc(newhunk, newalloc);
X		}
X		if (i >= newmin) {
X		    strcpy(newhunk+newsize, newmark);
X		    newwanted++;
X		}
X		else {
X		    strcpy(newhunk+newsize, "  ");
X		}
X		strcpy(newhunk+newsize+2,line);
X		newsize += len;
X	    }
X	    prenewmax = newmax;
X	    prenewend = newend;
X	}
X    }
X
X    if (preoldend >= 0) {
X	dumphunk();
X    }
X}
X
Xvoid
Xdumphunk()
X{
X    int i;
X    char *line;
X    int len;
X
X    for (i = preoldmax + 1; i <= preoldend; i++) {
X	line = getold(i);
X	if (!line) {
X	    preoldend = i - 1;
X	    break;
X	}
X	len = strlen(line) + 2;
X	if (oldsize + len + 1 >= oldalloc) {
X	    oldalloc *= 2;
X	    oldhunk = realloc(oldhunk, oldalloc);
X	}
X	strcpy(oldhunk+oldsize, "  ");
X	strcpy(oldhunk+oldsize+2, line);
X	oldsize += len;
X    }
X    for (i = prenewmax + 1; i <= prenewend; i++) {
X	line = getnew(i);
X	if (!line) {
X	    prenewend = i - 1;
X	    break;
X	}
X	len = strlen(line) + 2;
X	if (newsize + len + 1 >= newalloc) {
X	    newalloc *= 2;
X	    newhunk = realloc(newhunk, newalloc);
X	}
X	strcpy(newhunk+newsize, "  ");
X	strcpy(newhunk+newsize+2, line);
X	newsize += len;
X    }
X    fputs("***************\n",stdout);
X    if (preoldbeg >= preoldend) {
X	printf("*** %d ****\n", preoldend);
X    } else {
X	printf("*** %d,%d ****\n", preoldbeg, preoldend);
X    }
X    if (oldwanted) {
X	fputs(oldhunk,stdout);
X    }
X    oldsize = 0;
X    *oldhunk = '\0';
X    if (prenewbeg >= prenewend) {
X	printf("--- %d ----\n", prenewend);
X    } else {
X	printf("--- %d,%d ----\n", prenewbeg, prenewend);
X    }
X    if (newwanted) {
X	fputs(newhunk,stdout);
X    }
X    newsize = 0;
X    *newhunk = '\0';
X}
X
Xchar *
Xgetold(targ)
Xint targ;
X{
X    static int oldline = 0;
X
X    while (fgets(buff, sizeof buff, oldfp) != Nullch) {
X	oldline++;
X	if (oldline == targ)
X	    return buff;
X    }
X    return Nullch;
X}
X
Xchar *
Xgetnew(targ)
Xint targ;
X{
X    static int newline = 0;
X
X    while (fgets(buff, sizeof buff, newfp) != Nullch) {
X	newline++;
X	if (newline == targ)
X	    return buff;
X    }
X    return Nullch;
X}
+ END-OF-FILE cdiff.c
chmod 'u=rw,g=r,o=r' 'cdiff.c'
set `wc -c 'cdiff.c'`
count=$1
case $count in
6400)	:;;
*)	echo 'Bad character count in ''cdiff.c' >&2
		echo 'Count should be 6400' >&2
esac
echo Extracting 'ioctl.c'
sed 's/^X//' > 'ioctl.c' << '+ END-OF-FILE ''ioctl.c'
X#include "lib.h"
X#include <minix/com.h>
X#include <sgtty.h>
X
XPUBLIC int ioctl(fd, request, u)
Xint fd;
Xint request;
Xunion {
X  struct sgttyb *argp;
X  struct tchars *argt;
X} u;
X
X{
X  int n;
X  long erase, kill, intr, quit, xon, xoff, eof, brk;
X
X  M.TTY_REQUEST = request;
X  M.TTY_LINE = fd;
X
X  switch(request) {
X     case TIOCSETP:
X	erase = u.argp->sg_erase & 0377;
X	kill = u.argp->sg_kill & 0377;
X	M.TTY_SPEK = (erase << 8) | kill;
X	M.TTY_FLAGS = u.argp->sg_flags;
X	M.TTY_SPEED = (u.argp->sg_ospeed << 8) | u.argp->sg_ispeed;
X	n = callx(FS, IOCTL);
X  	return(n);
X 
X     case TIOCSETC:
X  	intr = u.argt->t_intrc & 0377;
X  	quit = u.argt->t_quitc & 0377;
X  	xon  = u.argt->t_startc & 0377;
X  	xoff = u.argt->t_stopc & 0377;
X  	eof  = u.argt->t_eofc & 0377;
X  	brk  = u.argt->t_brkc & 0377;		/* not used at the moment */
X  	M.TTY_SPEK = (intr<<24) | (quit<<16) | (xon<<8) | (xoff<<0);
X  	M.TTY_FLAGS = (eof<<8) | (brk<<0);
X  	n = callx(FS, IOCTL);
X  	return(n);
X  	
X     case TIOCGETP:
X  	n = callx(FS, IOCTL);
X	u.argp->sg_erase = (M.TTY_SPEK >> 8) & 0377;
X	u.argp->sg_kill  = (M.TTY_SPEK >> 0) & 0377;
X  	u.argp->sg_flags = M.TTY_FLAGS;
X  	return(n);
X
X     case TIOCGETC:
X  	n = callx(FS, IOCTL);
X  	u.argt->t_intrc  = (M.TTY_SPEK >> 24) & 0377;
X  	u.argt->t_quitc  = (M.TTY_SPEK >> 16) & 0377;
X  	u.argt->t_startc = (M.TTY_SPEK >>  8) & 0377;
X  	u.argt->t_stopc  = (M.TTY_SPEK >>  0) & 0377;
X  	u.argt->t_eofc   = (M.TTY_FLAGS >> 8) & 0377;
X  	u.argt->t_brkc   = (M.TTY_FLAGS >> 8) & 0377;
X  	return(n);
X
X     default:
X	n = -1;
X	errno = -(EINVAL);
X	return(n);
X  }
X}
X
+ END-OF-FILE ioctl.c
chmod 'u=rw,g=r,o=r' 'ioctl.c'
set `wc -c 'ioctl.c'`
count=$1
case $count in
1561)	:;;
*)	echo 'Bad character count in ''ioctl.c' >&2
		echo 'Count should be 1561' >&2
esac
exit 0