[REVIEW] move tty lock/initial up in the stack
Poul-Henning Kamp
phk at phk.freebsd.dk
Sat Jun 19 08:16:06 GMT 2004
This patch moves the "lock/initial" facility known from sio(4) up
to the generic tty layer.
It adds two new flags to stty(1): -i and -l to manipulate the initial
and lock states and eliminates the tty[il]d# and cua[il]a# devices.
Subsequently I would like to move the tty/cua split up as well.
Poul-Henning
Index: bin/stty/stty.1
===================================================================
RCS file: /home/ncvs/src/bin/stty/stty.1,v
retrieving revision 1.28
diff -u -r1.28 stty.1
--- bin/stty/stty.1 6 Apr 2004 20:06:53 -0000 1.28
+++ bin/stty/stty.1 18 Jun 2004 11:43:40 -0000
@@ -41,6 +41,7 @@
.Nm
.Op Fl a | Fl e | Fl g
.Op Fl f Ar file
+.Op Fl i | Fl l
.Op operands
.Sh DESCRIPTION
The
@@ -83,6 +84,12 @@
.Nm
to restore the current terminal state as per
.St -p1003.2 .
+.It Fl i
+Operate on the "initial" settings which apply on first open.
+.It Fl l
+Operate on the "lock" settings.
+Please note that the lock settings act as flags, the bits set here
+indicate which parts of the initial settings it is impossible to change.
.El
.Pp
The following arguments are available to set the terminal
Index: bin/stty/stty.c
===================================================================
RCS file: /home/ncvs/src/bin/stty/stty.c,v
retrieving revision 1.22
diff -u -r1.22 stty.c
--- bin/stty/stty.c 6 Apr 2004 20:06:53 -0000 1.22
+++ bin/stty/stty.c 18 Jun 2004 11:36:57 -0000
@@ -60,15 +60,17 @@
{
struct info i;
enum FMT fmt;
- int ch;
+ int ch, iget, iset;
fmt = NOTSET;
i.fd = STDIN_FILENO;
opterr = 0;
+ iget = TIOCGETA;
+ iset = TIOCSETA;
while (optind < argc &&
strspn(argv[optind], "-aefg") == strlen(argv[optind]) &&
- (ch = getopt(argc, argv, "aef:g")) != -1)
+ (ch = getopt(argc, argv, "aef:gil")) != -1)
switch(ch) {
case 'a': /* undocumented: POSIX compatibility */
fmt = POSIX;
@@ -83,6 +85,14 @@
case 'g':
fmt = GFLAG;
break;
+ case 'i':
+ iget = TIOCGETAI;
+ iset = TIOCSETAI;
+ break;
+ case 'l':
+ iget = TIOCGETAL;
+ iset = TIOCSETAL;
+ break;
case '?':
default:
goto args;
@@ -91,7 +101,7 @@
args: argc -= optind;
argv += optind;
- if (tcgetattr(i.fd, &i.t) < 0)
+ if (ioctl(i.fd, iget, &i.t) < 0)
errx(1, "stdin isn't a terminal");
if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
err(1, "TIOCGETD");
@@ -144,7 +154,7 @@
usage();
}
- if (i.set && tcsetattr(i.fd, 0, &i.t) < 0)
+ if (i.set && ioctl(i.fd, iset, &i.t) < 0)
err(1, "tcsetattr");
if (i.wset && ioctl(i.fd, TIOCSWINSZ, &i.win) < 0)
warn("TIOCSWINSZ");
Index: sys/dev/sio/sio.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sio/sio.c,v
retrieving revision 1.438
diff -u -r1.438 sio.c
--- sys/dev/sio/sio.c 16 Jun 2004 09:46:56 -0000 1.438
+++ sys/dev/sio/sio.c 18 Jun 2004 13:06:42 -0000
@@ -89,9 +89,6 @@
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
#define CALLOUT_MASK 0x80
-#define CONTROL_MASK 0x60
-#define CONTROL_INIT_STATE 0x20
-#define CONTROL_LOCK_STATE 0x40
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
#define MINOR_TO_UNIT(mynor) ((((mynor) & ~0xffffU) >> (8 + 3)) \
| ((mynor) & 0x1f))
@@ -242,14 +239,6 @@
struct tty *tp; /* cross reference */
- /* Initial state. */
- struct termios it_in; /* should be in struct tty */
- struct termios it_out;
-
- /* Lock state. */
- struct termios lt_in; /* should be in struct tty */
- struct termios lt_out;
-
bool_t do_timestamp;
bool_t do_dcd_timestamp;
struct timeval timestamp;
@@ -271,7 +260,7 @@
struct resource *ioportres;
int ioportrid;
void *cookie;
- struct cdev *devs[6];
+ struct cdev *devs[2];
/*
* Data area for output buffers. Someday we should build the output
@@ -387,20 +376,18 @@
if (com == NULL)
return (ENXIO);
+ tp = com->tp;
/*
* set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
* (note, the lock rates really are boolean -- if non-zero, disallow
* speed changes)
*/
- com->it_in.c_ispeed = com->it_in.c_ospeed =
- com->lt_in.c_ispeed = com->lt_in.c_ospeed =
- com->it_out.c_ispeed = com->it_out.c_ospeed =
- com->lt_out.c_ispeed = com->lt_out.c_ospeed = comdefaultrate;
+ tp->t_init.c_ispeed = tp->t_init.c_ospeed =
+ tp->t_lock.c_ispeed = tp->t_lock.c_ospeed = comdefaultrate;
/*
* if we're open, change the running rate too
*/
- tp = com->tp;
if (tp && (tp->t_state & TS_ISOPEN)) {
tp->t_termios.c_ispeed =
tp->t_termios.c_ospeed = comdefaultrate;
@@ -441,7 +428,7 @@
return (0);
}
com->gone = TRUE;
- for (i = 0 ; i < 6; i++)
+ for (i = 0 ; i < 2; i++)
destroy_dev(com->devs[i]);
if (com->irqres) {
bus_teardown_intr(dev, com->irqres, com->cookie);
@@ -912,6 +899,7 @@
int rid;
struct resource *port;
int ret;
+ struct tty *tp;
rid = xrid;
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
@@ -964,28 +952,28 @@
rclk = DEFAULT_RCLK;
com->rclk = rclk;
+ tp = com->tp = ttymalloc(NULL);
/*
* We don't use all the flags from <sys/ttydefaults.h> since they
* are only relevant for logins. It's important to have echo off
* initially so that the line doesn't start blathering before the
* echo flag can be turned off.
*/
- com->it_in.c_iflag = 0;
- com->it_in.c_oflag = 0;
- com->it_in.c_cflag = TTYDEF_CFLAG;
- com->it_in.c_lflag = 0;
+ tp->t_init.c_iflag = 0;
+ tp->t_init.c_oflag = 0;
+ tp->t_init.c_cflag = TTYDEF_CFLAG;
+ tp->t_init.c_lflag = 0;
if (unit == comconsole) {
- com->it_in.c_iflag = TTYDEF_IFLAG;
- com->it_in.c_oflag = TTYDEF_OFLAG;
- com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
- com->it_in.c_lflag = TTYDEF_LFLAG;
- com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
- com->lt_out.c_ispeed = com->lt_out.c_ospeed =
- com->lt_in.c_ispeed = com->lt_in.c_ospeed =
- com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
+ tp->t_init.c_iflag = TTYDEF_IFLAG;
+ tp->t_init.c_oflag = TTYDEF_OFLAG;
+ tp->t_init.c_cflag = TTYDEF_CFLAG | CLOCAL;
+ tp->t_init.c_lflag = TTYDEF_LFLAG;
+ tp->t_lock.c_cflag = CLOCAL;
+ tp->t_lock.c_ispeed = tp->t_lock.c_ospeed =
+ tp->t_init.c_ispeed = tp->t_init.c_ospeed = comdefaultrate;
} else
- com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
- if (siosetwater(com, com->it_in.c_ispeed) != 0) {
+ tp->t_init.c_ispeed = tp->t_init.c_ospeed = TTYDEF_SPEED;
+ if (siosetwater(com, tp->t_init.c_ispeed) != 0) {
mtx_unlock_spin(&sio_lock);
/*
* Leave i/o resources allocated if this is a `cn'-level
@@ -996,8 +984,7 @@
return (ENOMEM);
}
mtx_unlock_spin(&sio_lock);
- termioschars(&com->it_in);
- com->it_out = com->it_in;
+ termioschars(&tp->t_init);
/* attempt to determine UART type */
printf("sio%d: type", unit);
@@ -1125,20 +1112,12 @@
minorbase = UNIT_TO_MINOR(unit);
com->devs[0] = make_dev(&sio_cdevsw, minorbase,
UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
- com->devs[1] = make_dev(&sio_cdevsw, minorbase | CONTROL_INIT_STATE,
- UID_ROOT, GID_WHEEL, 0600, "ttyid%r", unit);
- com->devs[2] = make_dev(&sio_cdevsw, minorbase | CONTROL_LOCK_STATE,
- UID_ROOT, GID_WHEEL, 0600, "ttyld%r", unit);
- com->devs[3] = make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK,
+ com->devs[1] = make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK,
UID_UUCP, GID_DIALER, 0660, "cuaa%r", unit);
- com->devs[4] = make_dev(&sio_cdevsw,
- minorbase | CALLOUT_MASK | CONTROL_INIT_STATE,
- UID_UUCP, GID_DIALER, 0660, "cuaia%r", unit);
- com->devs[5] = make_dev(&sio_cdevsw,
- minorbase | CALLOUT_MASK | CONTROL_LOCK_STATE,
- UID_UUCP, GID_DIALER, 0660, "cuala%r", unit);
- for (rid = 0; rid < 6; rid++)
+ for (rid = 0; rid < 2; rid++) {
com->devs[rid]->si_drv1 = com;
+ com->devs[rid]->si_tty = tp;
+ }
com->flags = flags;
com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
@@ -1199,9 +1178,7 @@
return (ENXIO);
if (com->gone)
return (ENXIO);
- if (mynor & CONTROL_MASK)
- return (0);
- tp = dev->si_tty = com->tp = ttymalloc(com->tp);
+ tp = dev->si_tty;
s = spltty();
/*
* We jump to this label after all non-interrupted sleeps to pick
@@ -1256,8 +1233,7 @@
tp->t_param = comparam;
tp->t_stop = comstop;
tp->t_dev = dev;
- tp->t_termios = mynor & CALLOUT_MASK
- ? com->it_out : com->it_in;
+ tp->t_termios = tp->t_init;
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
com->poll = com->no_irq;
com->poll_output = com->loses_outints;
@@ -1374,8 +1350,6 @@
struct tty *tp;
mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (0);
com = com_addr(MINOR_TO_UNIT(mynor));
if (com == NULL)
return (ENODEV);
@@ -1435,7 +1409,7 @@
*/
|| (!com->active_out
&& !(com->prev_modem_status & MSR_DCD)
- && !(com->it_in.c_cflag & CLOCAL))
+ && !(tp->t_init.c_cflag & CLOCAL))
|| !(tp->t_state & TS_ISOPEN)) {
(void)commctl(com, TIOCM_DTR, DMBIC);
if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
@@ -1468,8 +1442,6 @@
struct com_s *com;
mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (ENODEV);
com = com_addr(MINOR_TO_UNIT(mynor));
if (com == NULL || com->gone)
return (ENODEV);
@@ -1487,8 +1459,6 @@
int unit;
mynor = minor(dev);
- if (mynor & CONTROL_MASK)
- return (ENODEV);
unit = MINOR_TO_UNIT(mynor);
com = com_addr(unit);
@@ -1981,39 +1951,6 @@
com = com_addr(MINOR_TO_UNIT(mynor));
if (com == NULL || com->gone)
return (ENODEV);
- if (mynor & CONTROL_MASK) {
- struct termios *ct;
-
- switch (mynor & CONTROL_MASK) {
- case CONTROL_INIT_STATE:
- ct = mynor & CALLOUT_MASK ? &com->it_out : &com->it_in;
- break;
- case CONTROL_LOCK_STATE:
- ct = mynor & CALLOUT_MASK ? &com->lt_out : &com->lt_in;
- break;
- default:
- return (ENODEV); /* /dev/nodev */
- }
- switch (cmd) {
- case TIOCSETA:
- error = suser(td);
- if (error != 0)
- return (error);
- *ct = *(struct termios *)data;
- return (0);
- case TIOCGETA:
- *(struct termios *)data = *ct;
- return (0);
- case TIOCGETD:
- *(int *)data = TTYDISC;
- return (0);
- case TIOCGWINSZ:
- bzero(data, sizeof(struct winsize));
- return (0);
- default:
- return (ENOTTY);
- }
- }
tp = com->tp;
#if defined(COMPAT_43)
term = tp->t_termios;
@@ -2027,8 +1964,7 @@
if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
int cc;
struct termios *dt = (struct termios *)data;
- struct termios *lt = mynor & CALLOUT_MASK
- ? &com->lt_out : &com->lt_in;
+ struct termios *lt = &tp->t_lock;
dt->c_iflag = (tp->t_iflag & lt->c_iflag)
| (dt->c_iflag & ~lt->c_iflag);
Index: sys/kern/tty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty.c,v
retrieving revision 1.219
diff -u -r1.219 tty.c
--- sys/kern/tty.c 16 Jun 2004 09:47:12 -0000 1.219
+++ sys/kern/tty.c 18 Jun 2004 11:48:41 -0000
@@ -769,6 +769,8 @@
case TIOCSTI:
case TIOCSTOP:
case TIOCSWINSZ:
+ case TIOCSETAI:
+ case TIOCSETAL:
#if defined(COMPAT_43)
case TIOCLBIC:
case TIOCLBIS:
@@ -1129,6 +1131,24 @@
case TIOCGDRAINWAIT:
*(int *)data = tp->t_timeout / hz;
break;
+ case TIOCSETAI:
+ error = suser(td);
+ if (error)
+ return (error);
+ tp->t_init = *(struct termios *)data;
+ break;
+ case TIOCGETAI:
+ *(struct termios *)data = tp->t_init;
+ break;
+ case TIOCSETAL:
+ error = suser(td);
+ if (error)
+ return (error);
+ tp->t_lock = *(struct termios *)data;
+ break;
+ case TIOCGETAL:
+ *(struct termios *)data = tp->t_lock;
+ break;
default:
#if defined(COMPAT_43)
return (ttcompat(tp, cmd, data, flag));
Index: sys/sys/tty.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/tty.h,v
retrieving revision 1.81
diff -u -r1.81 tty.h
--- sys/sys/tty.h 17 Jun 2004 17:16:53 -0000 1.81
+++ sys/sys/tty.h 18 Jun 2004 11:42:43 -0000
@@ -94,6 +94,8 @@
struct selinfo t_rsel; /* Tty read/oob select. */
struct selinfo t_wsel; /* Tty write select. */
struct termios t_termios; /* Termios state. */
+ struct termios t_init; /* Initial termios state. */
+ struct termios t_lock; /* Locked termios state. */
struct winsize t_winsize; /* Window size. */
/* Start output. */
void (*t_oproc)(struct tty *);
Index: sys/sys/ttycom.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/ttycom.h,v
retrieving revision 1.20
diff -u -r1.20 ttycom.h
--- sys/sys/ttycom.h 10 May 2004 02:24:56 -0000 1.20
+++ sys/sys/ttycom.h 18 Jun 2004 11:51:35 -0000
@@ -73,7 +73,11 @@
/* 23-25 obsolete or unused */
#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
- /* 28-69 free */
+#define TIOCGETAI _IOR('t', 28, struct termios) /* get init params */
+#define TIOCSETAI _IOW('t', 29, struct termios) /* set init params */
+#define TIOCGETAL _IOR('t', 30, struct termios) /* get lock params */
+#define TIOCSETAL _IOW('t', 31, struct termios) /* set lock params */
+ /* 32-69 free */
/* 127-124 compat */
#define TIOCSBRK _IO('t', 123) /* set break bit */
#define TIOCCBRK _IO('t', 122) /* clear break bit */
--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
More information about the freebsd-current
mailing list