1139743Simp/*-
243412Snewton * Copyright (c) 1998 Mark Newton
343412Snewton * Copyright (c) 1994 Christos Zoulas
443412Snewton * All rights reserved.
543412Snewton *
643412Snewton * Redistribution and use in source and binary forms, with or without
743412Snewton * modification, are permitted provided that the following conditions
843412Snewton * are met:
943412Snewton * 1. Redistributions of source code must retain the above copyright
1043412Snewton *    notice, this list of conditions and the following disclaimer.
1143412Snewton * 2. Redistributions in binary form must reproduce the above copyright
1243412Snewton *    notice, this list of conditions and the following disclaimer in the
1343412Snewton *    documentation and/or other materials provided with the distribution.
1443412Snewton * 3. The name of the author may not be used to endorse or promote products
1543412Snewton *    derived from this software without specific prior written permission
1643412Snewton *
1743412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1843412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1943412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2043412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2143412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2243412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2643412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743412Snewton */
2843412Snewton
29116174Sobrien#include <sys/cdefs.h>
30116174Sobrien__FBSDID("$FreeBSD: releng/11.0/sys/compat/svr4/svr4_termios.c 199882 2009-11-28 16:30:06Z ed $");
31116174Sobrien
3243412Snewton#include <sys/param.h>
3343412Snewton#include <sys/proc.h>
3443412Snewton#include <sys/systm.h>
3543412Snewton#include <sys/file.h>
3643412Snewton#include <sys/filedesc.h>
37199882Sed#include <sys/tty.h>
3843412Snewton
3943412Snewton#include <sys/sysproto.h>
4043412Snewton
4165302Sobrien#include <compat/svr4/svr4.h>
4265302Sobrien#include <compat/svr4/svr4_util.h>
4365302Sobrien#include <compat/svr4/svr4_ioctl.h>
4465302Sobrien#include <compat/svr4/svr4_termios.h>
4543412Snewton
4643412Snewton#ifndef __CONCAT3
4743412Snewton# if __STDC__
4843412Snewton#  define __CONCAT3(a,b,c)	a ## b ## c
4943412Snewton# else
5043412Snewton#  define __CONCAT3(a,b,c)	a/**/b/**/c
5143412Snewton# endif
5243412Snewton#endif
5343412Snewton
5492761Salfredstatic u_long bsd_to_svr4_speed(u_long, u_long);
5592761Salfredstatic u_long svr4_to_bsd_speed(u_long, u_long);
5692761Salfredstatic void svr4_to_bsd_termios(const struct svr4_termios *,
5792761Salfred				     struct termios *, int);
5892761Salfredstatic void bsd_to_svr4_termios(const struct termios *,
5992761Salfred				     struct svr4_termios *);
6092761Salfredstatic void svr4_termio_to_termios(const struct svr4_termio *,
6192761Salfred					struct svr4_termios *);
6292761Salfredstatic void svr4_termios_to_termio(const struct svr4_termios *,
6392761Salfred					struct svr4_termio *);
6443412Snewton#ifdef DEBUG_SVR4
6592761Salfredstatic void print_svr4_termios(const struct svr4_termios *);
6692761Salfredstatic void print_bsd_termios(const struct termios *);
6743412Snewton#endif /* DEBUG_SVR4 */
6843412Snewton
6943412Snewton#define undefined_char(a,b)				/**/
7043412Snewton#define undefined_flag1(f,a,b)				/**/
7143412Snewton#define undefined_flag2(f,a,b,c1,t1,c2,t2)		/**/
7243412Snewton#define undefined_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4)	/**/
7343412Snewton
7443412Snewton#define svr4_to_bsd_char(a,b) \
7543412Snewton	if (new || __CONCAT3(SVR4_,a,b) < SVR4_NCC) { \
7643412Snewton		if (st->c_cc[__CONCAT3(SVR4_,a,b)] == SVR4_POSIX_VDISABLE) \
7743412Snewton			bt->c_cc[__CONCAT(a,b)] = _POSIX_VDISABLE; \
7843412Snewton		else \
7943412Snewton			bt->c_cc[__CONCAT(a,b)] = st->c_cc[__CONCAT3(SVR4_,a,b)]; \
8043412Snewton	}
8143412Snewton
8243412Snewton#define svr4_to_bsd_flag1(f,a,b) \
8343412Snewton	if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
8443412Snewton		if (st->f & __CONCAT3(SVR4_,a,b)) \
8543412Snewton			bt->f |= __CONCAT(a,b); \
8643412Snewton		else \
8743412Snewton			bt->f &= ~__CONCAT(a,b); \
8843412Snewton	}
8943412Snewton
9043412Snewton#define svr4_to_bsd_flag2(f,a,b,c1,t1,c2,t2) \
9143412Snewton	if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
9243412Snewton		bt->f &= ~__CONCAT(a,b); \
9343412Snewton		switch (st->f & __CONCAT3(SVR4_,a,b)) { \
9443412Snewton		case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \
9543412Snewton		case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \
9643412Snewton		} \
9743412Snewton	}
9843412Snewton
9943412Snewton#define svr4_to_bsd_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \
10043412Snewton	if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
10143412Snewton		bt->f &= ~__CONCAT(a,b); \
10243412Snewton		switch (st->f & __CONCAT3(SVR4_,a,b)) { \
10343412Snewton		case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \
10443412Snewton		case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \
10543412Snewton		case __CONCAT3(SVR4_,c3,t3): bt->f |= __CONCAT(c3,t3); break; \
10643412Snewton		case __CONCAT3(SVR4_,c4,t4): bt->f |= __CONCAT(c4,t4); break; \
10743412Snewton		} \
10843412Snewton	}
10943412Snewton
11043412Snewton
11143412Snewton#define bsd_to_svr4_char(a,b) \
11243412Snewton	if (bt->c_cc[__CONCAT(a,b)] == _POSIX_VDISABLE) \
11343412Snewton		st->c_cc[__CONCAT3(SVR4_,a,b)] = SVR4_POSIX_VDISABLE; \
11443412Snewton	else \
11543412Snewton		st->c_cc[__CONCAT3(SVR4_,a,b)] = bt->c_cc[__CONCAT(a,b)]
11643412Snewton
11743412Snewton#define bsd_to_svr4_flag1(f,a,b) \
11843412Snewton	if (bt->f & __CONCAT(a,b)) \
11943412Snewton		st->f |= __CONCAT3(SVR4_,a,b); \
12043412Snewton	else \
12143412Snewton		st->f &= ~__CONCAT3(SVR4_,a,b)
12243412Snewton
12343412Snewton#define bsd_to_svr4_flag2(f,a,b,c1,t1,c2,t2) \
12443412Snewton	st->f &= ~__CONCAT(a,b); \
12543412Snewton	switch (bt->f & __CONCAT(a,b)) { \
12643412Snewton	case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \
12743412Snewton	case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \
12843412Snewton	}
12943412Snewton
13043412Snewton#define bsd_to_svr4_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \
13143412Snewton	st->f &= ~__CONCAT(a,b); \
13243412Snewton	switch (bt->f & __CONCAT(a,b)) { \
13343412Snewton	case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \
13443412Snewton	case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \
13543412Snewton	case __CONCAT(c3,t3): st->f |= __CONCAT3(SVR4_,c3,t3); break; \
13643412Snewton	case __CONCAT(c4,t4): st->f |= __CONCAT3(SVR4_,c4,t4); break; \
13743412Snewton	}
13843412Snewton
13943412Snewton#ifdef DEBUG_SVR4
14043412Snewtonstatic void
14143412Snewtonprint_svr4_termios(st)
14243412Snewton	const struct svr4_termios *st;
14343412Snewton{
14443412Snewton	int i;
14543412Snewton	DPRINTF(("SVR4\niflag=%lo oflag=%lo cflag=%lo lflag=%lo\n",
14643412Snewton	    st->c_iflag, st->c_oflag, st->c_cflag, st->c_lflag));
14743412Snewton	DPRINTF(("cc: "));
14843412Snewton	for (i = 0; i < SVR4_NCCS; i++)
14943412Snewton		DPRINTF(("%o ", st->c_cc[i]));
15043412Snewton	DPRINTF(("\n"));
15143412Snewton}
15243412Snewton
15343412Snewton
15443412Snewtonstatic void
15543412Snewtonprint_bsd_termios(bt)
15643412Snewton	const struct termios *bt;
15743412Snewton{
15843412Snewton	int i;
15943412Snewton	uprintf("BSD\niflag=%o oflag=%o cflag=%o lflag=%o\n",
16043412Snewton	    bt->c_iflag, bt->c_oflag, bt->c_cflag, bt->c_lflag);
16143412Snewton	uprintf("cc: ");
16243412Snewton	for (i = 0; i < NCCS; i++)
16343412Snewton		uprintf("%o ", bt->c_cc[i]);
16443412Snewton	uprintf("\n");
16543412Snewton}
16643412Snewton#endif /* DEBUG_SVR4 */
16743412Snewton
16843412Snewtonstatic u_long
16943412Snewtonbsd_to_svr4_speed(sp, mask)
17043412Snewton	u_long sp;
17143412Snewton	u_long mask;
17243412Snewton{
17343412Snewton	switch (sp) {
17443412Snewton#undef getval
17543412Snewton#define getval(a,b)	case __CONCAT(a,b):	sp = __CONCAT3(SVR4_,a,b)
17643412Snewton	getval(B,0);
17743412Snewton	getval(B,50);
17843412Snewton	getval(B,75);
17943412Snewton	getval(B,110);
18043412Snewton	getval(B,134);
18143412Snewton	getval(B,150);
18243412Snewton	getval(B,200);
18343412Snewton	getval(B,300);
18443412Snewton	getval(B,600);
18543412Snewton	getval(B,1200);
18643412Snewton	getval(B,1800);
18743412Snewton	getval(B,2400);
18843412Snewton	getval(B,4800);
18943412Snewton	getval(B,9600);
19043412Snewton	getval(B,19200);
19143412Snewton	getval(B,38400);
19243412Snewton	getval(B,57600);
19343412Snewton	getval(B,115200);
19443412Snewton	default: sp = SVR4_B9600;	/* XXX */
19543412Snewton	}
19643412Snewton
19743412Snewton	while ((mask & 1) == 0) {
19843412Snewton		mask >>= 1;
19943412Snewton		sp <<= 1;
20043412Snewton	}
20143412Snewton
20243412Snewton	return sp;
20343412Snewton}
20443412Snewton
20543412Snewton
20643412Snewtonstatic u_long
20743412Snewtonsvr4_to_bsd_speed(sp, mask)
20843412Snewton	u_long sp;
20943412Snewton	u_long mask;
21043412Snewton{
21143412Snewton	while ((mask & 1) == 0) {
21243412Snewton		mask >>= 1;
21343412Snewton		sp >>= 1;
21443412Snewton	}
21543412Snewton
21643412Snewton	switch (sp & mask) {
21743412Snewton#undef getval
21843412Snewton#define getval(a,b)	case __CONCAT3(SVR4_,a,b):	return __CONCAT(a,b)
21943412Snewton	getval(B,0);
22043412Snewton	getval(B,50);
22143412Snewton	getval(B,75);
22243412Snewton	getval(B,110);
22343412Snewton	getval(B,134);
22443412Snewton	getval(B,150);
22543412Snewton	getval(B,200);
22643412Snewton	getval(B,300);
22743412Snewton	getval(B,600);
22843412Snewton	getval(B,1200);
22943412Snewton	getval(B,1800);
23043412Snewton	getval(B,2400);
23143412Snewton	getval(B,4800);
23243412Snewton	getval(B,9600);
23343412Snewton	getval(B,19200);
23443412Snewton	getval(B,38400);
23543412Snewton	getval(B,57600);
23643412Snewton	getval(B,115200);
23743412Snewton	default: return B9600;	/* XXX */
23843412Snewton	}
23943412Snewton}
24043412Snewton
24143412Snewton
24243412Snewtonstatic void
24343412Snewtonsvr4_to_bsd_termios(st, bt, new)
24443412Snewton	const struct svr4_termios	*st;
24543412Snewton	struct termios	 		*bt;
24643412Snewton	int				 new;
24743412Snewton{
24843412Snewton	/* control characters */
24943412Snewton	/*
25043412Snewton	 * We process VMIN and VTIME first,
25143412Snewton	 * because they are shared with VEOF and VEOL
25243412Snewton	 */
25343412Snewton	svr4_to_bsd_char(V,MIN);
25443412Snewton	svr4_to_bsd_char(V,TIME);
25543412Snewton
25643412Snewton	svr4_to_bsd_char(V,INTR);
25743412Snewton	svr4_to_bsd_char(V,QUIT);
25843412Snewton	svr4_to_bsd_char(V,ERASE);
25943412Snewton	svr4_to_bsd_char(V,KILL);
26043412Snewton	svr4_to_bsd_char(V,EOF);
26143412Snewton	svr4_to_bsd_char(V,EOL);
26243412Snewton	svr4_to_bsd_char(V,EOL2);
26343412Snewton	undefined_char(V,SWTCH);
26443412Snewton	svr4_to_bsd_char(V,START);
26543412Snewton	svr4_to_bsd_char(V,STOP);
26643412Snewton	svr4_to_bsd_char(V,SUSP);
26743412Snewton	svr4_to_bsd_char(V,DSUSP);
26843412Snewton	svr4_to_bsd_char(V,REPRINT);
26943412Snewton	svr4_to_bsd_char(V,DISCARD);
27043412Snewton	svr4_to_bsd_char(V,WERASE);
27143412Snewton	svr4_to_bsd_char(V,LNEXT);
27243412Snewton
27343412Snewton	/* Input modes */
27443412Snewton	svr4_to_bsd_flag1(c_iflag,I,GNBRK);
27543412Snewton	svr4_to_bsd_flag1(c_iflag,B,RKINT);
27643412Snewton	svr4_to_bsd_flag1(c_iflag,I,GNPAR);
27743412Snewton	svr4_to_bsd_flag1(c_iflag,P,ARMRK);
27843412Snewton	svr4_to_bsd_flag1(c_iflag,I,NPCK);
27943412Snewton	svr4_to_bsd_flag1(c_iflag,I,STRIP);
28043412Snewton	svr4_to_bsd_flag1(c_iflag,I,NLCR);
28143412Snewton	svr4_to_bsd_flag1(c_iflag,I,GNCR);
28243412Snewton	svr4_to_bsd_flag1(c_iflag,I,CRNL);
28343412Snewton	undefined_flag1(c_iflag,I,UCLC);
28443412Snewton	svr4_to_bsd_flag1(c_iflag,I,XON);
28543412Snewton	svr4_to_bsd_flag1(c_iflag,I,XANY);
28643412Snewton	svr4_to_bsd_flag1(c_iflag,I,XOFF);
28743412Snewton	svr4_to_bsd_flag1(c_iflag,I,MAXBEL);
28843412Snewton	undefined_flag1(c_iflag,D,OSMODE);
28943412Snewton
29043412Snewton	/* Output modes */
29143412Snewton	svr4_to_bsd_flag1(c_oflag,O,POST);
29243412Snewton	undefined_flag1(c_oflag,O,LCUC);
29343412Snewton	svr4_to_bsd_flag1(c_oflag,O,NLCR);
29443412Snewton	undefined_flag1(c_oflag,O,CRNL);
29543412Snewton	undefined_flag1(c_oflag,O,NOCR);
29643412Snewton	undefined_flag1(c_oflag,O,NLRET);
29743412Snewton	undefined_flag1(c_oflag,O,FILL);
29843412Snewton	undefined_flag1(c_oflag,O,FDEL);
29943412Snewton	undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1);
30043412Snewton	undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3);
30143412Snewton	undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3);
30243412Snewton	undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1);
30343412Snewton	undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1);
30443412Snewton	undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1);
30543412Snewton	undefined_flag1(c_oflag,P,AGEOUT);
30643412Snewton	undefined_flag1(c_oflag,W,RAP);
30743412Snewton
30843412Snewton	/* Control modes */
30943412Snewton	bt->c_ospeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CBAUD);
31043412Snewton	svr4_to_bsd_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8)
31143412Snewton	svr4_to_bsd_flag1(c_cflag,C,STOPB);
31243412Snewton	svr4_to_bsd_flag1(c_cflag,C,READ);
31343412Snewton	svr4_to_bsd_flag1(c_cflag,P,ARENB);
31443412Snewton	svr4_to_bsd_flag1(c_cflag,P,ARODD);
31543412Snewton	svr4_to_bsd_flag1(c_cflag,H,UPCL);
31643412Snewton	svr4_to_bsd_flag1(c_cflag,C,LOCAL);
31743412Snewton	undefined_flag1(c_cflag,R,CV1EN);
31843412Snewton	undefined_flag1(c_cflag,X,MT1EN);
31943412Snewton	undefined_flag1(c_cflag,L,OBLK);
32043412Snewton	undefined_flag1(c_cflag,X,CLUDE);
32143412Snewton	bt->c_ispeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CIBAUD);
32243412Snewton	undefined_flag1(c_cflag,P,AREXT);
32343412Snewton
32443412Snewton	/* line discipline modes */
32543412Snewton	svr4_to_bsd_flag1(c_lflag,I,SIG);
32643412Snewton	svr4_to_bsd_flag1(c_lflag,I,CANON);
32743412Snewton	undefined_flag1(c_lflag,X,CASE);
32843412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHO);
32943412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHOE);
33043412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHOK);
33143412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHONL);
33243412Snewton	svr4_to_bsd_flag1(c_lflag,N,OFLSH);
33343412Snewton	svr4_to_bsd_flag1(c_lflag,T,OSTOP);
33443412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHOCTL);
33543412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHOPRT);
33643412Snewton	svr4_to_bsd_flag1(c_lflag,E,CHOKE);
33743412Snewton	undefined_flag1(c_lflag,D,EFECHO);
33843412Snewton	svr4_to_bsd_flag1(c_lflag,F,LUSHO);
33943412Snewton	svr4_to_bsd_flag1(c_lflag,P,ENDIN);
34043412Snewton	svr4_to_bsd_flag1(c_lflag,I,EXTEN);
34143412Snewton}
34243412Snewton
34343412Snewton
34443412Snewtonstatic void
34543412Snewtonbsd_to_svr4_termios(bt, st)
34643412Snewton	const struct termios 	*bt;
34743412Snewton	struct svr4_termios	*st;
34843412Snewton{
34943412Snewton	/* control characters */
35043412Snewton	/*
35143412Snewton	 * We process VMIN and VTIME first,
35243412Snewton	 * because they are shared with VEOF and VEOL
35343412Snewton	 */
35443412Snewton	bsd_to_svr4_char(V,MIN);
35543412Snewton	bsd_to_svr4_char(V,TIME);
35643412Snewton	bsd_to_svr4_char(V,INTR);
35743412Snewton	bsd_to_svr4_char(V,QUIT);
35843412Snewton	bsd_to_svr4_char(V,ERASE);
35943412Snewton	bsd_to_svr4_char(V,KILL);
36043412Snewton	bsd_to_svr4_char(V,EOF);
36143412Snewton	bsd_to_svr4_char(V,EOL);
36243412Snewton	bsd_to_svr4_char(V,EOL2);
36343412Snewton	undefined_char(V,SWTCH);
36443412Snewton	bsd_to_svr4_char(V,START);
36543412Snewton	bsd_to_svr4_char(V,STOP);
36643412Snewton	bsd_to_svr4_char(V,SUSP);
36743412Snewton	bsd_to_svr4_char(V,DSUSP);
36843412Snewton	bsd_to_svr4_char(V,REPRINT);
36943412Snewton	bsd_to_svr4_char(V,DISCARD);
37043412Snewton	bsd_to_svr4_char(V,WERASE);
37143412Snewton	bsd_to_svr4_char(V,LNEXT);
37243412Snewton
37343412Snewton	/* Input modes */
37443412Snewton	bsd_to_svr4_flag1(c_iflag,I,GNBRK);
37543412Snewton	bsd_to_svr4_flag1(c_iflag,B,RKINT);
37643412Snewton	bsd_to_svr4_flag1(c_iflag,I,GNPAR);
37743412Snewton	bsd_to_svr4_flag1(c_iflag,P,ARMRK);
37843412Snewton	bsd_to_svr4_flag1(c_iflag,I,NPCK);
37943412Snewton	bsd_to_svr4_flag1(c_iflag,I,STRIP);
38043412Snewton	bsd_to_svr4_flag1(c_iflag,I,NLCR);
38143412Snewton	bsd_to_svr4_flag1(c_iflag,I,GNCR);
38243412Snewton	bsd_to_svr4_flag1(c_iflag,I,CRNL);
38343412Snewton	undefined_flag1(c_iflag,I,UCLC);
38443412Snewton	bsd_to_svr4_flag1(c_iflag,I,XON);
38543412Snewton	bsd_to_svr4_flag1(c_iflag,I,XANY);
38643412Snewton	bsd_to_svr4_flag1(c_iflag,I,XOFF);
38743412Snewton	bsd_to_svr4_flag1(c_iflag,I,MAXBEL);
38843412Snewton	undefined_flag1(c_iflag,D,OSMODE);
38943412Snewton
39043412Snewton	/* Output modes */
39143412Snewton	bsd_to_svr4_flag1(c_oflag,O,POST);
39243412Snewton	undefined_flag1(c_oflag,O,LCUC);
39343412Snewton	bsd_to_svr4_flag1(c_oflag,O,NLCR);
39443412Snewton	undefined_flag1(c_oflag,O,CRNL);
39543412Snewton	undefined_flag1(c_oflag,O,NOCR);
39643412Snewton	undefined_flag1(c_oflag,O,NLRET);
39743412Snewton	undefined_flag1(c_oflag,O,FILL);
39843412Snewton	undefined_flag1(c_oflag,O,FDEL);
39943412Snewton	undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1);
40043412Snewton	undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3);
40143412Snewton	undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3);
40243412Snewton	undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1);
40343412Snewton	undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1);
40443412Snewton	undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1);
40543412Snewton	undefined_flag1(c_oflag,P,AGEOUT);
40643412Snewton	undefined_flag1(c_oflag,W,RAP);
40743412Snewton
40843412Snewton	/* Control modes */
40943412Snewton	st->c_cflag &= ~SVR4_CBAUD;
41043412Snewton	st->c_cflag |= bsd_to_svr4_speed(bt->c_ospeed, SVR4_CBAUD);
41143412Snewton	bsd_to_svr4_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8)
41243412Snewton	bsd_to_svr4_flag1(c_cflag,C,STOPB);
41343412Snewton	bsd_to_svr4_flag1(c_cflag,C,READ);
41443412Snewton	bsd_to_svr4_flag1(c_cflag,P,ARENB);
41543412Snewton	bsd_to_svr4_flag1(c_cflag,P,ARODD);
41643412Snewton	bsd_to_svr4_flag1(c_cflag,H,UPCL);
41743412Snewton	bsd_to_svr4_flag1(c_cflag,C,LOCAL);
41843412Snewton	undefined_flag1(c_cflag,R,CV1EN);
41943412Snewton	undefined_flag1(c_cflag,X,MT1EN);
42043412Snewton	undefined_flag1(c_cflag,L,OBLK);
42143412Snewton	undefined_flag1(c_cflag,X,CLUDE);
42243412Snewton	st->c_cflag &= ~SVR4_CIBAUD;
42343412Snewton	st->c_cflag |= bsd_to_svr4_speed(bt->c_ispeed, SVR4_CIBAUD);
42443412Snewton
42543412Snewton	undefined_flag1(c_oflag,P,AREXT);
42643412Snewton
42743412Snewton	/* line discipline modes */
42843412Snewton	bsd_to_svr4_flag1(c_lflag,I,SIG);
42943412Snewton	bsd_to_svr4_flag1(c_lflag,I,CANON);
43043412Snewton	undefined_flag1(c_lflag,X,CASE);
43143412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHO);
43243412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHOE);
43343412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHOK);
43443412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHONL);
43543412Snewton	bsd_to_svr4_flag1(c_lflag,N,OFLSH);
43643412Snewton	bsd_to_svr4_flag1(c_lflag,T,OSTOP);
43743412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHOCTL);
43843412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHOPRT);
43943412Snewton	bsd_to_svr4_flag1(c_lflag,E,CHOKE);
44043412Snewton	undefined_flag1(c_lflag,D,EFECHO);
44143412Snewton	bsd_to_svr4_flag1(c_lflag,F,LUSHO);
44243412Snewton	bsd_to_svr4_flag1(c_lflag,P,ENDIN);
44343412Snewton	bsd_to_svr4_flag1(c_lflag,I,EXTEN);
44443412Snewton}
44543412Snewton
44643412Snewton
44743412Snewtonstatic void
44843412Snewtonsvr4_termio_to_termios(t, ts)
44943412Snewton	const struct svr4_termio	*t;
45043412Snewton	struct svr4_termios		*ts;
45143412Snewton{
45243412Snewton	int i;
45343412Snewton
45443412Snewton	ts->c_iflag = (svr4_tcflag_t) t->c_iflag;
45543412Snewton	ts->c_oflag = (svr4_tcflag_t) t->c_oflag;
45643412Snewton	ts->c_cflag = (svr4_tcflag_t) t->c_cflag;
45743412Snewton	ts->c_lflag = (svr4_tcflag_t) t->c_lflag;
45843412Snewton
45943412Snewton	for (i = 0; i < SVR4_NCC; i++)
46043412Snewton		ts->c_cc[i] = (svr4_cc_t) t->c_cc[i];
46143412Snewton}
46243412Snewton
46343412Snewton
46443412Snewtonstatic void
46543412Snewtonsvr4_termios_to_termio(ts, t)
46643412Snewton	const struct svr4_termios	*ts;
46743412Snewton	struct svr4_termio		*t;
46843412Snewton{
46943412Snewton	int i;
47043412Snewton
47143412Snewton	t->c_iflag = (u_short) ts->c_iflag;
47243412Snewton	t->c_oflag = (u_short) ts->c_oflag;
47343412Snewton	t->c_cflag = (u_short) ts->c_cflag;
47443412Snewton	t->c_lflag = (u_short) ts->c_lflag;
47543412Snewton	t->c_line = 0;	/* XXX */
47643412Snewton
47743412Snewton	for (i = 0; i < SVR4_NCC; i++)
47843412Snewton		t->c_cc[i] = (u_char) ts->c_cc[i];
47943412Snewton}
48043412Snewton
48143412Snewtonint
48283366Sjuliansvr4_term_ioctl(fp, td, retval, fd, cmd, data)
48343412Snewton	struct file *fp;
48483366Sjulian	struct thread *td;
48543412Snewton	register_t *retval;
48643412Snewton	int fd;
48743412Snewton	u_long cmd;
48843412Snewton	caddr_t data;
48943412Snewton{
49043412Snewton	struct termios 		bt;
49143412Snewton	struct svr4_termios	st;
49243412Snewton	struct svr4_termio	t;
49343412Snewton	int			error, new;
49443412Snewton
49543412Snewton	*retval = 0;
49643412Snewton
49780114Sassar	DPRINTF(("TERM ioctl %lx\n", cmd));
49843412Snewton
49943412Snewton	switch (cmd) {
50043412Snewton	case SVR4_TCGETA:
50143412Snewton	case SVR4_TCGETS:
50243412Snewton		DPRINTF(("ioctl(TCGET%c);\n", cmd == SVR4_TCGETA ? 'A' : 'S'));
503102003Srwatson		if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt,
504102003Srwatson		    td->td_ucred, td)) != 0)
50543412Snewton			return error;
50643412Snewton
50743412Snewton		memset(&st, 0, sizeof(st));
50843412Snewton		bsd_to_svr4_termios(&bt, &st);
50943412Snewton
51043412Snewton#ifdef DEBUG_SVR4
51143412Snewton		print_bsd_termios(&bt);
51243412Snewton		print_svr4_termios(&st);
51343412Snewton#endif /* DEBUG_SVR4 */
51443412Snewton
51543412Snewton		if (cmd == SVR4_TCGETA) {
51643412Snewton		    svr4_termios_to_termio(&st, &t);
51743412Snewton		    return copyout(&t, data, sizeof(t));
51843412Snewton		}
51943412Snewton		else  {
52043412Snewton		    return copyout(&st, data, sizeof(st));
52143412Snewton		}
52243412Snewton
52343412Snewton	case SVR4_TCSETA:
52443412Snewton	case SVR4_TCSETS:
52543412Snewton	case SVR4_TCSETAW:
52643412Snewton	case SVR4_TCSETSW:
52743412Snewton	case SVR4_TCSETAF:
52843412Snewton	case SVR4_TCSETSF:
52943412Snewton	        DPRINTF(("TCSET{A,S,AW,SW,AF,SF}\n"));
53043412Snewton		/* get full BSD termios so we don't lose information */
531102003Srwatson		if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt,
532102003Srwatson		    td->td_ucred, td)) != 0)
53343412Snewton			return error;
53443412Snewton
53543412Snewton		switch (cmd) {
53643412Snewton		case SVR4_TCSETS:
53743412Snewton		case SVR4_TCSETSW:
53843412Snewton		case SVR4_TCSETSF:
53943412Snewton			if ((error = copyin(data, &st, sizeof(st))) != 0)
54043412Snewton				return error;
54143412Snewton			new = 1;
54243412Snewton			break;
54343412Snewton
54443412Snewton		case SVR4_TCSETA:
54543412Snewton		case SVR4_TCSETAW:
54643412Snewton		case SVR4_TCSETAF:
54743412Snewton			if ((error = copyin(data, &t, sizeof(t))) != 0)
54843412Snewton				return error;
54943412Snewton
55043412Snewton			svr4_termio_to_termios(&t, &st);
55143412Snewton			new = 0;
55243412Snewton			break;
55343412Snewton
55443412Snewton		default:
55543412Snewton			return EINVAL;
55643412Snewton		}
55743412Snewton
55843412Snewton		svr4_to_bsd_termios(&st, &bt, new);
55943412Snewton
56043412Snewton		switch (cmd) {
56143412Snewton		case SVR4_TCSETA:
56243412Snewton		case SVR4_TCSETS:
56343412Snewton			DPRINTF(("ioctl(TCSET[A|S]);\n"));
56443412Snewton			cmd = TIOCSETA;
56543412Snewton			break;
56643412Snewton		case SVR4_TCSETAW:
56743412Snewton		case SVR4_TCSETSW:
56843412Snewton			DPRINTF(("ioctl(TCSET[A|S]W);\n"));
56943412Snewton			cmd = TIOCSETAW;
57043412Snewton			break;
57143412Snewton		case SVR4_TCSETAF:
57243412Snewton		case SVR4_TCSETSF:
57343412Snewton			DPRINTF(("ioctl(TCSET[A|S]F);\n"));
57443412Snewton			cmd = TIOCSETAF;
57543412Snewton			break;
57643412Snewton		}
57743412Snewton
57843412Snewton#ifdef DEBUG_SVR4
57943412Snewton		print_bsd_termios(&bt);
58043412Snewton		print_svr4_termios(&st);
58143412Snewton#endif /* DEBUG_SVR4 */
58243412Snewton
583102003Srwatson		return fo_ioctl(fp, cmd, (caddr_t) &bt, td->td_ucred, td);
58443412Snewton
58543412Snewton	case SVR4_TIOCGWINSZ:
58643412Snewton	        DPRINTF(("TIOCGWINSZ\n"));
58743412Snewton		{
58843412Snewton			struct svr4_winsize ws;
58943412Snewton
590102003Srwatson			error = fo_ioctl(fp, TIOCGWINSZ, (caddr_t) &ws,
591102003Srwatson			    td->td_ucred, td);
59243412Snewton			if (error)
59343412Snewton				return error;
59443412Snewton			return copyout(&ws, data, sizeof(ws));
59543412Snewton		}
59643412Snewton
59743412Snewton	case SVR4_TIOCSWINSZ:
59843412Snewton	        DPRINTF(("TIOCSWINSZ\n"));
59943412Snewton		{
60043412Snewton			struct svr4_winsize ws;
60143412Snewton
60243412Snewton			if ((error = copyin(data, &ws, sizeof(ws))) != 0)
60343412Snewton				return error;
604102003Srwatson			return fo_ioctl(fp, TIOCSWINSZ, (caddr_t) &ws,
605102003Srwatson			    td->td_ucred, td);
60643412Snewton		}
60743412Snewton
60843412Snewton	default:
60943412Snewton	        DPRINTF(("teleport to STREAMS ioctls...\n"));
61083366Sjulian		return svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, data);
61143412Snewton	}
61243412Snewton}
613