Date: Sat, 19 Jun 2004 10:15:58 +0200 From: Poul-Henning Kamp <phk@phk.freebsd.dk> To: current@freebsd.org Subject: [REVIEW] move tty lock/initial up in the stack Message-ID: <61609.1087632958@critter.freebsd.dk>
next in thread | raw e-mail | index | archive | help
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@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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?61609.1087632958>