[REVIEW] move tty lock/initial up in the stack

From: Poul-Henning Kamp (phk_at_phk.freebsd.dk)
Date: 06/19/04

  • Next message: Stefan Ehmann: "Re: Lost buffers with mounted ext2fs"
    To: current@freebsd.org
    Date: Sat, 19 Jun 2004 10:15:58 +0200
    
    

    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.
    _______________________________________________
    freebsd-current@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-current
    To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"
    

  • Next message: Stefan Ehmann: "Re: Lost buffers with mounted ext2fs"

    Relevant Pages

    • [patch] Re: dlopen() and dlclose() are not MT-safe?
      ... retrieving revision 1.112 ... diff -u -r1.112 rtld.c ... BTW do you know the reason why lock is released before calling ... static void objlist_clear; ...
      (freebsd-hackers)
    • Re: Whats the point of __KERNEL_SYSCALLS__?
      ... retrieving revision 1.4 ... diff -u -p -r1.4 process.c ... -static int errno; ... * calls - which means inline code for fork too, ...
      (Linux-Kernel)
    • New Patch [was: Re: cvs rm sys/posix4 && enable sem]
      ... posix4/sched.h to sys/psched.h in this patch). ... "steps" as, in place of a repo-copy, I'll commit the diff to ... retrieving revision 1.2 ... +To compile this driver into the kernel, ...
      (freebsd-arch)
    • CONFIG_64_BIT
      ... retrieving revision 1.3 ... diff -u -p -r1.3 Kconfig ... config MMU ...
      (Linux-Kernel)
    • Re: vmstats entries type
      ... while updating the 64-bit per cpu counters. ... retrieving revision 1.80 ... diff -u -r1.80 vmstat.c ...
      (freebsd-current)