Subject: kern/2887: Adding defaults to tty's
To: None <gnats-bugs@gnats.netbsd.org>
From: None <wrstuden@loki.stanford.edu>
List: netbsd-bugs
Date: 10/22/1996 21:44:31
>Number:         2887
>Category:       kern
>Synopsis:       tty's don't support per-port settable defaults.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 22 22:05:02 1996
>Last-Modified:
>Originator:     Bill Studenmund
>Organization:
Studenmund Consulting
	
>Release:        mid-May for most source, 1.2 for src/dev/*<NetBSD-current source date>
>Environment:
all netbsd
	
System: NetBSD pokey 1.1B NetBSD 1.1B (MACFS) #31: Sun Oct 13 19:00:52 PDT 1996 croot@pokey:/y1/src11/sys/arch/mac68k/compile/MACFS mac68k


>Description:
	All the tty drivers I could see folow the same procedure on
first open. They set the tty's termios structure up from compile-time
defaults. This procedure prohibits per-port, run-time customization of tty
settings.
	
>How-To-Repeat:
	
>Fix:

Below I enclose an implimentation of per-port defaults. I mentioned this idea
on tech-kern, and got no arguments (actually no comment). As suggested 
on tech-kern, I add a defaults struct termios to struct tty. I add two
new IOCTL's to manipulate these defaults. These defaults are initialized
in ttymalloc (since it takes all steps to set up a tty, it seemed like a good
addition). As such, the only necessary change to a driver to take advantage
of the defaults is for the code in the open routine which will set up the
defaults during a first-open. Currently drivers fill each field in the
t_termios on first-open (or first first-open for some). This proposal replaces
all that code with a bcopy from the defaults to the working struct termios,
so most drivers will become slightly simpler. As the driver must be (slightly)
changed to use defaults, drivers can opt not to use defaults. I do not forsee
pty's supporting defaults. :-)

The two IOCTL's will either return the current defaults struct termios, or
copy the current termios to the defualt termios. I opted against permitting
arbitrary defaults setting as the defaults need to be verified by the
param routine for the driver. This routine both verifies and sets in hardware
the values in its termios. To change the rotine to optionally just verify would
be a major code change. The only point where the distinction is important is
if the port is in use while defaults are being set; the port will be left in
the default state. As defaults would typically only be changed at boot or
while the port is down, no difficulty is forseen.

I also enclose two new libc routines to use these IOCTL's, and changes
to bin/stty to impliment a "-D" option to set and review the defaults.
Due to my unfamiliarity with man page formatting, I only updated the
stty manpage to document the changes. I do not feel comfortable writing
the formatted man page for the libc changes, though could write an
unformatted starter if asked.

The one open question with these changes is who should be able to change the
defaults. At present, no permission checks are made (other than the ability
to open the tty). I an uncertain what requirements are best, and perhaps an
option similar to UCONSOLE will be needed.

I enclose a new tcgetdef.c, tcsetdef.c, and diffs to all other files changed in
the kernel. As an example, I also enclose patches to the mac68k z8530 tty driver,
the M.I. z8530 tty driver, and dev/isa/com.c. The mac68k patch is larger than
the other two as the mac68k had internally implimented defaults (w/o modifiability).

**** Begin src/lib/libc/termios/tcgetdef.c ****
/*	$NetBSD: tcgetattr.c,v 1.2 1995/06/26 23:05:55 jtc Exp $	*/

/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)termios.c	8.2 (Berkeley) 2/21/94";
#else
static char rcsid[] = "$NetBSD: tcgetattr.c,v 1.2 1995/06/26 23:05:55 jtc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */

#include <sys/ioctl.h>
#include <termios.h>

int
tcgetdef(fd, t)
	int fd;
	struct termios *t;
{
	return (ioctl(fd, TIOCGDEFS, t));
}
**** end src/lib/libc/termios/tcgetdef.c ****

**** begin src/lib/libc/termios/tcsetdef.c ****
/*	$NetBSD: tcsetdef.c,v 0.1 1996/09/14 23:06:06 wrs Exp $	*/

/*-
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)termios.c	8.2 (Berkeley) 2/21/94";
#else
static char rcsid[] = "$NetBSD: tcsetdef.c,v 0.1 1996/09/14 23:06:06 wrs Exp $";
#endif
#endif /* LIBC_SCCS and not lint */

#include <sys/ioctl.h>
#include <termios.h>
#include <errno.h>

int
tcsetdef(fd)
	int fd;
{
	return (ioctl(fd, TIOCSDEFS, 0));
}
**** end src/lib/libc/termios/tcsetdef.c ****

Now for the diff's:
*** /sys/sys/termios.h.orig	Tue Sep 17 22:50:02 1996
--- /sys/sys/termios.h	Tue Sep 17 22:51:56 1996
***************
*** 249,254 ****
--- 249,256 ----
  int	cfsetospeed __P((struct termios *, speed_t));
  int	tcgetattr __P((int, struct termios *));
  int	tcsetattr __P((int, int, const struct termios *));
+ int	tcgetdef  __P((int, struct termios *));
+ int	tcsetdef  __P((int));
  int	tcdrain __P((int));
  int	tcflow __P((int, int));
  int	tcflush __P((int, int));
*** /sys/kern/tty.c.orig	Sun Aug 25 21:26:06 1996
--- /sys/kern/tty.c	Thu Sep 19 22:50:49 1996
***************
*** 891,896 ****
--- 891,910 ----
  			pgsignal(tp->t_pgrp, SIGWINCH, 1);
  		}
  		break;
+ 	case TIOCGDEFS: {			/* get tty default termios */
+ 		struct termios *t = (struct termios *)data;
+ 
+                 bcopy(&tp->t_defaults, t, sizeof(struct termios));
+ 		printf("Did TIOCGDEFS.\n");
+ 		break;
+ 	}
+ 	case TIOCSDEFS:			/* set tty default termios */
+ 		/* set defaults to current state since driver already
+ 		 * verified these settings. */
+ 		/* XXX do we need to check permissions? */
+ 		bcopy(&tp->t_termios, &tp->t_defaults, sizeof(struct termios));
+ 		printf("Did TIOCSDEFS.\n");
+ 		break;
  	default:
  #ifdef COMPAT_OLDTTY
  		return (ttcompat(tp, cmd, data, flag, p));
***************
*** 2026,2031 ****
--- 2040,2046 ----
  
  /*
   * Allocate a tty structure and its associated buffers.
+  * Also set up default termios structure.
   */
  struct tty *
  ttymalloc()
***************
*** 2039,2044 ****
--- 2054,2067 ----
  	clalloc(&tp->t_canq, 1024, 1);
  	/* output queue doesn't need quoting */
  	clalloc(&tp->t_outq, 1024, 0);
+ 	/* now set up default termios */
+ 	tp->t_defaults.c_cflag = TTYDEF_CFLAG;
+ 	tp->t_defaults.c_iflag = TTYDEF_IFLAG;
+ 	tp->t_defaults.c_lflag = TTYDEF_LFLAG;
+ 	tp->t_defaults.c_oflag = TTYDEF_OFLAG;
+ 	tp->t_defaults.c_ispeed = tp->t_defaults.c_ospeed = TTYDEF_SPEED;
+ 	ttychars(tp);
+ 	bcopy(&tp->t_cc, &tp->t_defaults.c_cc, sizeof(tp->t_cc));
  	return(tp);
  }
  
--- /sys/sys/tty.h.orig	Sun Aug 25 21:16:53 1996
+++ /sys/sys/tty.h	Sun Sep 15 22:26:17 1996
@@ -109,6 +109,7 @@
 	short	t_hiwat;		/* High water mark. */
 	short	t_lowat;		/* Low water mark. */
 	short	t_gen;			/* Generation number. */
+	struct	termios t_defaults;	/* Tty default termios state. */
 };
 
 #define	t_cc		t_termios.c_cc
@@ -116,10 +117,16 @@
 #define	t_iflag		t_termios.c_iflag
 #define	t_ispeed	t_termios.c_ispeed
 #define	t_lflag		t_termios.c_lflag
-#define	t_min		t_termios.c_min
 #define	t_oflag		t_termios.c_oflag
 #define	t_ospeed	t_termios.c_ospeed
-#define	t_time		t_termios.c_time
+
+#define	t_d_cc		t_defaults.c_cc
+#define	t_d_cflag	t_defaults.c_cflag
+#define	t_d_iflag	t_defaults.c_iflag
+#define	t_d_ispeed	t_defaults.c_ispeed
+#define	t_d_lflag	t_defaults.c_lflag
+#define	t_d_oflag	t_defaults.c_oflag
+#define	t_d_ospeed	t_defaults.c_ospeed
 
 #define	TTIPRI	25			/* Sleep priority for tty reads. */
 #define	TTOPRI	26			/* Sleep priority for tty writes. */
--- /sys/sys/ttycom.h.orig	Sun Aug 25 21:13:17 1996
+++ /sys/sys/ttycom.h	Sun Aug 25 21:44:16 1996
@@ -129,6 +129,8 @@
 #define		TIOCFLAG_CLOCAL		0x02	/* set clocal on open */
 #define		TIOCFLAG_CRTSCTS	0x04	/* set crtscts on open */
 #define		TIOCFLAG_MDMBUF		0x08	/* set mdmbuf on open */
+#define	TIOCGDEFS	_IOR('t', 91, struct termios)	/* get tty defaults */
+#define TIOCSDEFS	 _IO('t', 90)		/* set tty defaults to current */
 
 #define	TTYDISC		0		/* termios tty line discipline */
 #define	TABLDISC	3		/* tablet discipline */
*** /sys/arch/mac68k/dev/z8530tty.c.960810	Sat Aug 10 10:08:13 1996
--- /sys/arch/mac68k/dev/z8530tty.c	Sun Oct  6 15:16:30 1996
***************
*** 160,172 ****
  	zst->zst_swflags = cf->cf_flags;	/* softcar, etc. */
  	zst->zst_hwflags = args->hwflags;
  	
- 	zst->zst_cflag = ZSTTY_DEF_CFLAG;	/* set up defaults */
- 	zst->zst_iflag = TTYDEF_IFLAG;		/* an ioctl can change */
- 	zst->zst_lflag = TTYDEF_LFLAG;		/* these values, modifying */
- 	zst->zst_oflag = TTYDEF_OFLAG;		/* initial defaults */
- 	zst->zst_ispeed = zst->zst_ospeed = cs->cs_defspeed;
- 	/* zst_cc set after tty is malloc'd */
- 
  	dev = makedev(ZSTTY_MAJOR, tty_unit);
  
  	if (zst->zst_swflags)
--- 160,165 ----
***************
*** 197,204 ****
  	tp->t_oproc = zsstart;
  	tp->t_param = zsparam;
  	tp->t_hwiflow = zshwiflow;
- 	ttychars(tp);
- 	bcopy(tp->t_cc, zst->zst_cc, sizeof(tp->t_cc));
  
  	zst->zst_tty = tp;
  	zst->zst_rbhiwat =  zstty_rbuf_size;	/* impossible value */
--- 190,195 ----
***************
*** 227,239 ****
  	if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) {
  		/* This unit is the console. */
  		zst->zst_swflags |= TIOCFLAG_SOFTCAR;
- 		/* Call _param so interrupts get enabled. */
- 		bcopy(&zst->zst_termios, &tp->t_termios, sizeof(struct termios));
- 		/* copy the whole termios in as the first "first open" won't
- 		 * do it since the speed != 0 */
  		cs->cs_defspeed = zs_getspeed(cs);
! 		tp->t_ispeed = cs->cs_defspeed;
! 		tp->t_ospeed = cs->cs_defspeed;
  		(void) zsparam(tp, &tp->t_termios);
  	} else {
  		/* Not the console; may need reset. */
--- 218,228 ----
  	if (zst->zst_hwflags & ZS_HWFLAG_CONSOLE) {
  		/* This unit is the console. */
  		zst->zst_swflags |= TIOCFLAG_SOFTCAR;
  		cs->cs_defspeed = zs_getspeed(cs);
! 		tp->t_d_ispeed = cs->cs_defspeed;
! 		tp->t_d_ospeed = cs->cs_defspeed;
! 		bcopy(&tp->t_defaults, &tp->t_termios, sizeof(struct termios));
! 		/* Call _param so interrupts get enabled. */
  		(void) zsparam(tp, &tp->t_termios);
  	} else {
  		/* Not the console; may need reset. */
***************
*** 317,335 ****
  	s = spltty();
  
  	if ((tp->t_state & TS_ISOPEN) == 0) {
! 		if ((tp->t_ispeed == 0) || (zst->zst_resetdef)) {
! 			/* First open. Executed if either the tty
! 			 * was uninitialized, or if we choose to
! 			 * reset defaults w/ each open. */
! 			bcopy(&zst->zst_termios, &tp->t_termios,
! 			    sizeof(struct termios));
! 			if (zst->zst_swflags & TIOCFLAG_CLOCAL)
! 				tp->t_cflag |= CLOCAL;
! 			if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
! 				tp->t_cflag |= CRTSCTS;
! 			if (zst->zst_swflags & TIOCFLAG_MDMBUF)
! 				tp->t_cflag |= MDMBUF;
! 		}
  		(void) zsparam(tp, &tp->t_termios);
  		ttsetwater(tp);
  		/* Flush any pending input. */
--- 306,319 ----
  	s = spltty();
  
  	if ((tp->t_state & TS_ISOPEN) == 0) {
! 		bcopy(&tp->t_defaults, &tp->t_termios,
! 		    sizeof(struct termios));
! 		if (zst->zst_swflags & TIOCFLAG_CLOCAL)
! 			tp->t_cflag |= CLOCAL;
! 		if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
! 			tp->t_cflag |= CRTSCTS;
! 		if (zst->zst_swflags & TIOCFLAG_MDMBUF)
! 			tp->t_cflag |= MDMBUF;
  		(void) zsparam(tp, &tp->t_termios);
  		ttsetwater(tp);
  		/* Flush any pending input. */
*** /sys/arch/mac68k/dev/zs.c.orig	Sat Aug 10 09:49:55 1996
--- /sys/arch/mac68k/dev/zs.c	Thu Sep 19 22:59:49 1996
***************
*** 368,383 ****
  		zst->zst_hwflags |= ZS_HWFLAG_IGCTS;
  
  	if (theflags & ZSMAC_RAW) {
! 		zst->zst_cflag = ZSTTY_RAW_CFLAG;
! 		zst->zst_iflag = ZSTTY_RAW_IFLAG;
! 		zst->zst_lflag = ZSTTY_RAW_LFLAG;
! 		zst->zst_oflag = ZSTTY_RAW_OFLAG;
  		printf(" (raw defaults)");
  	}
  	if (theflags & ZSMAC_LOCALTALK) {
  		printf(" shielding from LocalTalk");
! 		zst->zst_ospeed = tp->t_ospeed = 1;
! 		zst->zst_ispeed = tp->t_ispeed = 1;
  		cs->cs_defspeed = 1;
  		cs->cs_creg[ZSRR_BAUDLO] = cs->cs_preg[ZSRR_BAUDLO] = 0xff;
  		cs->cs_creg[ZSRR_BAUDHI] = cs->cs_preg[ZSRR_BAUDHI] = 0xff;
--- 371,386 ----
  		zst->zst_hwflags |= ZS_HWFLAG_IGCTS;
  
  	if (theflags & ZSMAC_RAW) {
! 		tp->t_d_cflag = ZSTTY_RAW_CFLAG;
! 		tp->t_d_iflag = ZSTTY_RAW_IFLAG;
! 		tp->t_d_lflag = ZSTTY_RAW_LFLAG;
! 		tp->t_d_oflag = ZSTTY_RAW_OFLAG;
  		printf(" (raw defaults)");
  	}
  	if (theflags & ZSMAC_LOCALTALK) {
  		printf(" shielding from LocalTalk");
! 		tp->t_d_ospeed = tp->t_ospeed = 1;
! 		tp->t_d_ispeed = tp->t_ispeed = 1;
  		cs->cs_defspeed = 1;
  		cs->cs_creg[ZSRR_BAUDLO] = cs->cs_preg[ZSRR_BAUDLO] = 0xff;
  		cs->cs_creg[ZSRR_BAUDHI] = cs->cs_preg[ZSRR_BAUDHI] = 0xff;
*** /src/lib/libc/termios/Makefile.inc.orig	Sun Sep 15 21:30:20 1996
--- /src/lib/libc/termios/Makefile.inc	Sun Sep 15 21:30:55 1996
***************
*** 4,10 ****
  
  SRCS+=	cfgetispeed.c cfgetospeed.c cfmakeraw.c cfsetispeed.c cfsetospeed.c \
  	cfsetspeed.c tcdrain.c tcflow.c tcflush.c tcgetattr.c tcgetpgrp.c \
! 	tcsendbreak.c tcsetattr.c tcsetpgrp.c
  
  MAN+=	tcgetpgrp.3 tcsendbreak.3 tcsetattr.3 tcsetpgrp.3
  
--- 4,10 ----
  
  SRCS+=	cfgetispeed.c cfgetospeed.c cfmakeraw.c cfsetispeed.c cfsetospeed.c \
  	cfsetspeed.c tcdrain.c tcflow.c tcflush.c tcgetattr.c tcgetpgrp.c \
! 	tcsendbreak.c tcsetattr.c tcsetpgrp.c tcsetdef.c tcgetdef.c
  
  MAN+=	tcgetpgrp.3 tcsendbreak.3 tcsetattr.3 tcsetpgrp.3
  
*** /src/bin/stty/stty.1.orig	Wed Oct  9 22:35:01 1996
--- /src/bin/stty/stty.1	Wed Oct  9 22:37:40 1996
***************
*** 46,51 ****
--- 46,52 ----
  .Nm stty
  .Op Fl a | Fl e | Fl g
  .Op Fl f Ar file
+ .Op Fl D
  .Op operands
  .Sh DESCRIPTION
  The
***************
*** 88,93 ****
--- 89,98 ----
  .Nm stty
  to restore the current terminal state as per
  .St -p1003.2 .
+ .It Fl D
+ Display and/or modify the per-tty defaults for this tty rather than
+ the current status. Note: changing the defaults requires changing
+ the current settings to match the defaults.
  .El
  .Pp
  The following arguments are available to set the terminal
*** /src/bin/stty/stty.c.orig	Sat Sep 14 12:37:22 1996
--- /src/bin/stty/stty.c	Mon Sep 23 16:47:10 1996
***************
*** 68,82 ****
  {
  	struct info i;
  	enum FMT fmt;
! 	int ch;
  
  	fmt = NOTSET;
  	i.fd = STDIN_FILENO;
  
  	opterr = 0;
  	while (optind < argc &&
! 	    strspn(argv[optind], "-aefg") == strlen(argv[optind]) &&
! 	    (ch = getopt(argc, argv, "aef:g")) != -1)
  		switch(ch) {
  		case 'a':		/* undocumented: POSIX compatibility */
  			fmt = POSIX;
--- 68,82 ----
  {
  	struct info i;
  	enum FMT fmt;
! 	int ch, do_defaults = 0;
  
  	fmt = NOTSET;
  	i.fd = STDIN_FILENO;
  
  	opterr = 0;
  	while (optind < argc &&
! 	    strspn(argv[optind], "-aefgD") == strlen(argv[optind]) &&
! 	    (ch = getopt(argc, argv, "aef:gD")) != -1)
  		switch(ch) {
  		case 'a':		/* undocumented: POSIX compatibility */
  			fmt = POSIX;
***************
*** 91,96 ****
--- 91,99 ----
  		case 'g':
  			fmt = GFLAG;
  			break;
+ 		case 'D':
+ 			do_defaults = 1;
+ 			break;
  		case '?':
  		default:
  			goto args;
***************
*** 101,108 ****
  
  	if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
  		err(1, "TIOCGETD");
! 	if (tcgetattr(i.fd, &i.t) < 0)
! 		err(1, "tcgetattr");
  	if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0)
  		warn("TIOCGWINSZ");
  
--- 104,115 ----
  
  	if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
  		err(1, "TIOCGETD");
! 	if (do_defaults) {
! 		if (tcgetdef(i.fd, &i.t) < 0)
! 			err(1, "tcgetdef");
! 	} else
! 		if (tcgetattr(i.fd, &i.t) < 0)
! 			err(1, "tcgetattr");
  	if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0)
  		warn("TIOCGWINSZ");
  
***************
*** 152,157 ****
--- 159,166 ----
  
  	if (i.set && tcsetattr(i.fd, 0, &i.t) < 0)
  		err(1, "tcsetattr");
+ 	if (i.set && do_defaults && tcsetdef(i.fd) < 0)
+ 		err(1, "tcsetdef");
  	if (i.wset && ioctl(i.fd, TIOCSWINSZ, &i.win) < 0)
  		warn("TIOCSWINSZ");
  	exit(0);
*** /sys/dev/ic/z8530tty.c.orig	Sun Oct 20 18:26:21 1996
--- /sys/dev/ic/z8530tty.c	Sun Oct 20 18:28:30 1996
***************
*** 357,374 ****
  
  	if ((tp->t_state & TS_ISOPEN) == 0) {
  		/* First open. */
! 		ttychars(tp);
! 		tp->t_iflag = TTYDEF_IFLAG;
! 		tp->t_oflag = TTYDEF_OFLAG;
! 		tp->t_cflag = ZSTTY_DEF_CFLAG;
  		if (zst->zst_swflags & TIOCFLAG_CLOCAL)
  			tp->t_cflag |= CLOCAL;
  		if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
  			tp->t_cflag |= CRTSCTS;
  		if (zst->zst_swflags & TIOCFLAG_MDMBUF)
  			tp->t_cflag |= MDMBUF;
- 		tp->t_lflag = TTYDEF_LFLAG;
- 		tp->t_ispeed = tp->t_ospeed = cs->cs_defspeed;
  		(void) zsparam(tp, &tp->t_termios);
  		ttsetwater(tp);
  		/* Flush any pending input. */
--- 357,370 ----
  
  	if ((tp->t_state & TS_ISOPEN) == 0) {
  		/* First open. */
! 		bcopy(&tp->t_defaults, &tp->t_termios,
! 			sizeof(struct termios));
  		if (zst->zst_swflags & TIOCFLAG_CLOCAL)
  			tp->t_cflag |= CLOCAL;
  		if (zst->zst_swflags & TIOCFLAG_CRTSCTS)
  			tp->t_cflag |= CRTSCTS;
  		if (zst->zst_swflags & TIOCFLAG_MDMBUF)
  			tp->t_cflag |= MDMBUF;
  		(void) zsparam(tp, &tp->t_termios);
  		ttsetwater(tp);
  		/* Flush any pending input. */
*** /sys/dev/isa/com.c.orig	Sun Oct 20 18:30:26 1996
--- /sys/dev/isa/com.c	Sun Oct 20 18:31:42 1996
***************
*** 539,559 ****
  	tp->t_dev = dev;
  	if (!ISSET(tp->t_state, TS_ISOPEN)) {
  		SET(tp->t_state, TS_WOPEN);
! 		ttychars(tp);
! 		tp->t_iflag = TTYDEF_IFLAG;
! 		tp->t_oflag = TTYDEF_OFLAG;
  		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
  			tp->t_cflag = comconscflag;
- 		else
- 			tp->t_cflag = TTYDEF_CFLAG;
  		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
  			SET(tp->t_cflag, CLOCAL);
  		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
  			SET(tp->t_cflag, CRTSCTS);
  		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
  			SET(tp->t_cflag, MDMBUF);
- 		tp->t_lflag = TTYDEF_LFLAG;
- 		tp->t_ispeed = tp->t_ospeed = comdefaultrate;
  
  		s = spltty();
  
--- 539,554 ----
  	tp->t_dev = dev;
  	if (!ISSET(tp->t_state, TS_ISOPEN)) {
  		SET(tp->t_state, TS_WOPEN);
! 		bcopy(&tp->t_defaults, &tp->t_termios,
! 			sizeof(struct termios));
  		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
  			tp->t_cflag = comconscflag;
  		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
  			SET(tp->t_cflag, CLOCAL);
  		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
  			SET(tp->t_cflag, CRTSCTS);
  		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
  			SET(tp->t_cflag, MDMBUF);
  
  		s = spltty();
  
>Audit-Trail:
>Unformatted: