Opened 3 years ago

Closed 12 months ago

#17344 closed task (fixed)

Use the generic tty code in the tty driver

Reported by: pulkomandy Owned by: nobody
Priority: normal Milestone: R1/beta5
Component: Drivers/TTY Version: R1/beta3
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

Currently the tty driver (src/add-ons/kernel/drivers/tty) has a its own implementation of the TTY code and does not use the generic one (src/add-ons/kernel/generic/tty).

The driver provides pseudo-TTYs and is used mainly for Terminal. The generic module is already used by all real serial port drivers (pc_serial and usb_serial).

Unfortunately the code in the driver and the generic module is a bit different and the differences should be investigated. They are mainly:

  • In the driver, there are two functions handling "background read" and "background write". They don't exist in the generic code.
  • In the driver, master and slave side of a TTY share the same settings. In the generic module, they have separate settings, and the settings must be explicityl copied from one side to the other
  • In the driver, the TTYs are locked with a simple mutex. In the generic module, a recursive lock is used. The recursive lock is needed because of the way the settings are synchronized between the two sides of a TTY: the tty_control function calls the driver "service functon", which in turns calls tty_control again, resulting in an attempt to re-acquire the lock.
  • In the driver, a fixed list of TTYs is allocated at init. The module can allocate any number of TTYs. This results in some differences in the API and implementation, but it should not be a problem: the driver can just ask the TTY module to create a certain number of TTYs when it initializes.

Change History (6)

comment:1 by X512, 3 years ago

The driver provides pseudo-TTYs and is used mainly for Terminal.

Why Terminal need special kernel components to work? That sounds wrong. Can't pipes etc. be used instead?

comment:2 by pulkomandy, 3 years ago

This article provides a good overview of what's the use of a TTY: http://linusakesson.net/programming/tty/index.php

It is part legacy (both from UNIX and BeOS) and part because it does a lot more than you'd think and a lot more than a pipe does, and for good reasons in some cases.

In addition to what a pipe does (just sending and receiving bytes between two processes), there is at least:

  • Signal delivery. When you press control+C, when the terminal is resized, this is notified to the applications using signals,
  • Tracking of which application and process group is on the foreground, so that the signals can be sent to the right place,
  • The "line discipline" and managing which characters are sent by the backspace key, or even a buffering system to send only one line at a time to the application instead of sending each keystroke (it saves a lot of performance to have all the keyboard processing done in Terminal when possible). This can be configured by the application, and Terminal or the TTY must implement it.

You could maybe kind-of emulate all of this with pipes and kill (and a lot of headaches). But you couldn't do it using the standard APIs which means you will need to rewrite ncurses, libreadline/libedit, and probably the shell interpreter and its management of foreground/background jobs to use your new system. Probably you also need to rewrite ssh client and servers, which also make use of it (it is not at all limited or specific to Terminal).

TTY are just a higher level way to make two process communicate than pipes. They do a reasonable job at it and our implementation is not that big or complicated. I don't think it is worth the effort of replacing it at the moment.

comment:3 by waddlesplash, 3 years ago

PulkoMandy's TTY locking fixes were merged in hrev55558.

comment:4 by waddlesplash, 2 years ago

From mmlr:

it's been too long and I have no recollection of the state there. if there's anything to know it would be in the commit messages. there were some differences that made it non-trivial to merge the two, probably around locking. the earliest commit message suggests that the main difference was dropped BeOS compatibility.

comment:5 by pulkomandy, 2 years ago

The locking was indeed different, but the new locking was not working properly, there were race conditions. This is what I changed, and now the "new" tty system uses the same locking design as the old one.

As far as I can tell, the only difference now is that the old tty system has a preallocated hardcoded list of ttys. The new system can allocate them dynamically.

I think the static list is needed for beos api compatibility. Our Terminal expects pty/tty devices to pre-exist in /dev.

I think the old module could be stripped to do just that: provide these hardcoded pty/tty pairs in /dev. It could do so by using the new generic tty module. And maybe we can rename it to pty (pseudo-teletype) to make it more clear what it is used for: basically anything not related to an actual serial port.

comment:6 by waddlesplash, 12 months ago

Milestone: UnscheduledR1/beta5
Resolution: fixed
Status: newclosed

Accomplished in hrev56981.

Note: See TracTickets for help on using tickets.