I've recently been working out how best to wire up a serial cable for a vintage plotter, and it's thrown me down the rabbit hole of RS-232.

As far as I can tell, many RS-232 devices which act as DTEs (e.g. my plotter, DEC terminals) seem to prefer to use the DTR and DSR pins for hardware flow control on the local link (i.e. between the device and a locally connected computer, or between the device and a modem), and use the RTS and CTS pins a way of controlling the connection that a modem holds to a remote site (I think that this might go back to half-duplex modems).

However Linux seems only to have built-in support using the RTS and CTS pins for hardware flow control (and uses them much as these other devices use DTR and DSR), even though I think UARTs would have had equivalent hardware support for either or both modes of operation.

Am I right in understanding that Linux computers are unusual compared to other DTEs? Or did other operating systems work the same? What about other Unices? Is there a historical reason for the choice of RTS/CTS? Was RTS/CTS more common than I've realised?

  • 8
    Ah the joys (ha!) of getting RS-232 to work on random hardware back in the day, usually requiring a breakout box or two. DTE/DCE was all well and good for teletype connections. Much less so for a PC talking to all sorts of things - which is which under which conditions? Flow control was quite common since it ignores the which is which question.
    – Jon Custer
    Commented Nov 6, 2023 at 17:53
  • 5
    The problem is that RS-232 wasn't designed symmetrically. The RTS/CTS pins are for sending from a terminal to a modem, but there's no defined signals to do the equivalent in the other direction. Using DTR/DSR is a kludge borne of necessity. Commented Nov 7, 2023 at 4:06
  • 1
    On pre-Windows PC-DOS on real IBM PC-ATs, my university department taught 2D and 3D CAD using two different programs, and the lab I managed had HP pen plotters, with DTR being the "I'm busy" handshake signal. However, one CAD program expected to see this on CTS, the other on DSR, neither being configurable - so the DTR out from the plotter had to be wired to BOTH flow control inputs on the PC serial port. Commented Nov 7, 2023 at 5:42
  • 2
    Note that Linux actually has a stty option crtscts to use CTS/RTS handshake, and another cdtrdsr option to use DTR/DSR. I used the former extensively in my Unix experience last century, but never heard of the latter until much later, so I'm quite sure that is a Linux extension which Unix classically didn't have. Commented Nov 7, 2023 at 16:36
  • 1
    Yes, this is more or less what my question is about. If you look at the documentation for stty in GNU coreutils, you'll see it described. But if you run stty with --help on Linux, you'll find it isn't listed. That's because Linux doesn't support DTR/DSR handshaking, and so it is compiled out with an #ifdef CDTRDSR. Commented Nov 7, 2023 at 16:56

7 Answers 7


In short, Linux is a Unix-like operating system kernel and does things like other Unix-like operating systems. The least common denominator for different Unix-like systems is the POSIX standard, which, among other things, defines the API for how serial ports are accessed in a POSIX-compliant system.

Different serial devices work differently and how they have worked over time has changed.

But most common use for any implementation for serial ports has been modems.

The RS-232 standard only defines the electrical interface between a data terminal and data communication equipment, which means: connector, voltage levels, and signal names - not exactly how they are used outside the scope of half-duplex modems. It does not even define how the data bits are sent; everyone just expects the data to be handled by UARTs that use an asynchronous start-stop framing protocol.

Only in the RS-232-E revision made in 1991 was it acknowledged that the RTS/CTS handshake could be used symmetrically, about 30 years after the first version was standardized.

Simplified, DTR and DSR are used as handshakes between PC and modem that the data set is ready (modem is powered up) and the data terminal is ready (a terminal program opened the serial port). The modem may ignore any data if DTR is not set by PC. The terminal program (or rather, the serial device driver, which is configured by the terminal program when device is opened) running on the PC may ignore any data if DSR is not set by the modem.

The modem may also disconnect the phone connection if DTR drops, like if the user quits the terminal program.

CTS and RTS are then used for flow control. Maybe you had a modem which communicates at 28800 bps over the phone line, but can communicate at 115200 bps with the PC. So if the PC wants to transfer a bunch of data, the modem's FIFO buffers get full quickly and it must notify the PC to stop sending until some data has been sent over the phone line and there is room in the buffers again. Same thing with PC: if it has receive buffers that start to get full, it can tell the modem to stop for a moment.

Now, printers and plotters are not modems, and RS-232 implementations vary. They might have a single set of handshake pins for some hardware reason or simply because it was not necessary.

RTS is commonly also used as transmit enable for half-duplex lines such as RS-485 or maybe some radio packet modems.

So yeah, many OSes, Windows, Linux, and other Unixes and BSDs assume that if you want flow control, it's RTS/CTS and not DTR/DSR. Some serial ports may even support RTS/CTS handshake in hardware with DMA transfers and DTR/DSR are just slow software programmable GPIO.

And that's why many devices need a weird custom cable between host and the device: to allow either the device hardware or software program to see the expected signals in expected ways.

  • 1
    That's really interesting, because it seems like the complete reverse of what I've been reading. I wonder if I just have things backwards. I'll try to dig out some examples and update my question if appropriate. Do you happen to have an example of a modem that you are sure works as you describe? Commented Nov 6, 2023 at 18:26
  • 6
    Having had the misfortune to have to deal with half-duplex comms lines on PDP-11, I concur; DTS/DTR is basically link initialization and teardown, RTS/CTS is line turnaround discipline (I didn't have to worry much about 'sending too fast for the modem').
    – dave
    Commented Nov 6, 2023 at 18:30
  • 1
    @PeterRussell Well, all modems I've ever seen. And the names of the signals indicate their use too; DTR = Data Terminal Ready, DSR = Data Set Ready, RTS = Ready To Send, CTS = Clear To Send. It would be quite strange if DTR/DSR were used for flow control of sending data and RTS/CTS simply determining if device is ready.
    – Justme
    Commented Nov 6, 2023 at 19:17
  • 1
    @Justme well at the time the signals were named flow control wasn't common at all (AIUI), and the way to avoid overrunning buffers would be to... not overrun the buffers. On half-duplex modems the meaning of RTS and CTS was subtly different from what it is today (from what I've read, I never used a real modem) - meaning we want to take a turn at sending data / Ok, it's our turn now. Not unrelated, but not how it's used by Linux. Commented Nov 6, 2023 at 19:32
  • 5
    Nope. RTS means "I am ready to send and want to send", and is part of the protocol between local computer/terminal and local modem. CTS is the modem's response and means "you are clear to start sending". In half-duplex, the modem typically enables its transmitter on getting RTS and before responding CTS.
    – dave
    Commented Nov 6, 2023 at 21:02

Linux started as a hobbyist operating system. It was in no position to set any kind of standard. Instead, Linux implemented what hobbyists needed at that time. When Linux got popular, the convention of dropping DTR to hang up (and thus avoiding the <pause>+++<pause> sequence) and using RTS/CTS for flow control between the modem buffer and the PC was already established as de-facto standard for PC modem use, which is why Linux implements this behaviour. I refer to the already present answers for the history of RS-232 that may have led to this convention.

IIRC, in Germany, it was mandatory for a modem to unconditionally implement hang-up-on-DTR-drop to avoid that a modem blocks a phone line if the computer failed. Modems behaving otherwise were not allowed to be connected to public lines.

  • 1
    I think it's becoming clear that the behaviour of the modems that were in use in the 90s is absolutely what Linux was aiming to support. What seems strange is that they didn't also support the other style that was seems like it was quite common. Commented Nov 7, 2023 at 8:52
  • 1
    @PeterRussell Not 90's, 70's. Linux didn't exist in the 70's, but Unix did, and that's where Linux got it. The "other style" didn't exist in the 70's.
    – John Doty
    Commented Nov 8, 2023 at 12:26
  • @Michael Karcher In Germany in the 1980s, it was mandatory for a modem to be leased from the German Post Office, then still a branch of the federal government. These modems behaved in non-standard ways compared to other modems on the market, and leasing them was expensive and bureaucratic. Thus, many people used acoustic couplers or illegal modems - still expensive because fixed-fee unlimited-time local calls had been abolished around 1981, except in Berlin. Things improved with the liberalization of the 1990s,
    – TeaRex
    Commented Nov 9, 2023 at 9:27

Serial port standards weren't. Obligatory XKCD.

Different devices had different preferred handshaking lines. And even if all DCE worked the same and all DTE worked the same, you had situations of DTE - DTE (e.g., computer to printer). And situations where one line was needed to force auto-dialing of a modem but another was used for actual flow-control handshaking. And so on.

You would start with the manuals - some good, some bad - and then simple LED testers like this one:

RS232 tester

and then go on to a full breakout box like this one:

breakout box

and hopefully you would figure out what really worked. The manuals weren't always correct. The UARTs (or maybe other components) weren't always so good, so some systems just wouldn't handshake properly (or fast enough) at the highest available speeds. And so on.

I eventually created adapters - 6 or 8 wire RJ connectors to DB-25 or DB-9 for my most common configurations. And then something new would come along.

But I always tried my best to get hardware handshaking working - I still don't like software handshaking.

  • 2
    Software handshaking is the worst. If you send any binary data over the line, you're guaranteed to trip it accidentally. Commented Nov 7, 2023 at 4:11
  • Yes, the problem is using RS232 without DCE. It wasn't designed for that. So, we got various incompatible kludges.
    – John Doty
    Commented Nov 8, 2023 at 13:41

The history is that Linux copied Unix. People at Bell Labs developed Unix. RS232 was specifically intended for modem interfaces. Unix naturally used AT&T RS232 modems to communicate through the phone system. In those days, the faster AT&T modems were "half duplex": they could only communicate data in one direction at at time. Modems in those days had no memory, so they lost any data they couldn't transmit. If the line was idle, RTS would configure the DCE to send data, and CTS would indicate that it was so configured.

DTR and DCR were about the status of the DCE/DTE connection, not the data flow. DCD indicated that the modem on the other end was connected. They weren't used for flow control.

At higher level, sophisticated terminals used XON/XOFF characters, not RS232, for flow control (they might not even be connected via an RS232 interface). Dumb terminals were expected to be capable of continuously receiving characters without flow control, and if the mechanics couldn't keep up, the sender had to send padding. Locally connected dumb terminals often didn't use RS232 at all: the interfaces were simple current loops.

Thus, in the 1970's, at physical level using AT&T modems, RTS/CTS was the flow control mechanism. That's where Linux got it.

  • From my faint memory the knowledge was that for high data rate "hardware flow control" (CTS/RTS) was more reliable than "software flow control" (XON/XOFF). You seem to say the opposite somehow. Also from my memory is: "Never combine hardware and software flow control". Finally on "DCD indicated that the modem on the other end was connected": Isn't it the indication that both modems had established a logical connection (baud rate, etc.)? Whether the remote modem is actually connected to anything is a different aspect IMHO.
    – U. Windl
    Commented Nov 8, 2023 at 9:20
  • 1
    @U.Windl You're thinking of flow control in a different sense from "which side may use the line now", which is the original purpose of CTS/RTS. RS232 was for DCE/DTE connections: it wasn't designed to inform the DTE about the readiness of the DTE at the other end of the link. That's what XON/XOFF was for. Links with adequately smart DTE at both ends used a packet protocol (Bisync, g-protocol, ...). Modems were dumb: DCD simply meant the modem was hearing the tone it expected. Negotiation between modems of protocol and baud rate didn't exist when RS232 was designed.
    – John Doty
    Commented Nov 8, 2023 at 11:39
  • 1
    @U.Windl: it's not that sophisticated terminals used XON/XOFF in preference to other methods, it's that the only method they supported was XON/XOFF. I'd have to check the manuals, but hardware flow control didn't arrive to the DEC VT line until quite late (VT 320?). The VT100 could be connected via a so-called 20 mA current loop, with no additional signals.
    – ninjalj
    Commented Nov 8, 2023 at 16:00
  • @JohnDoty: Xon/Xoff existed for the purpose of requesting that a remote TTY turn its tape reader on and off (whenever the remote tape reader was on, it would repeatedly advance the tape and send whatever pattern of holes was over the sense fingers).
    – supercat
    Commented Nov 8, 2023 at 17:16
  • 1
    @supercat Yep. But it got repurposed.
    – John Doty
    Commented Nov 9, 2023 at 2:19

I've ended up doing quite a lot of research on this question now, and I'm going to try to provide my own answer. This is based on my own research, assumptions and a lot of guesses, not to mention input from other answers and comments. I'd very much welcome corrections. I intend to edit further to include more links to evidence.

The short answer

The short answer, as others have said, is that presumably the reason Linux implemented support for RTS/CTS flow control, and not DTR/DTS flow control is that RTS and CTS are the standard signals used for hardware flow control and DTR and DTS are not. That is both the de facto standard implemented by a very large number of devices, and the de jure standard described by the ITU and the EIA¹.

The very long answer

That prompts a bunch of other questions, if RTS/CTS flow control was the standard, why was DTR/DTS flow control even a thing? And was it really even a thing, or are some RS-232 devices just weird? Why wouldn't they just do RTS/CTS flow control? And if it was a thing, why wouldn't Linux implement that in addition to RTS/CTS flow control?

Many Devices use DTR or DTR/DTS Flow-Control

Just to illustrate that DTR/DTS flow-control is not something I have made up, here are some examples of devices from various well known manufacturers that used it:

  • Wyse WY50 Terminal (1983, subsequent Wyse Terminals too)
  • HP 7550A plotter (1985, probably older and newer HP serial plotters too)
  • DEC VT520 (1993, curiously older models in the series aren't documented to support hardware flow-control at all)
  • Epson Receipt Printers (Present day, although I bet they're continuing a long line)

All of these devices support deasserting the DTR line to show that they are too busy to handle more data, and none of them support using RTS for the same purpose. I bet that there are many, many other examples. I don't know which device was the first, or if it was written down anywhere as some sort of proposed standard. I'd be interested to know.

So why?

Modems are the key to understanding RS-232

JustMe said:

Different serial devices work differently and how they have worked over time has changed.

But most common use for any implementation for serial ports have been modems.

and I think this is correct. It seems that to understand the choices made in implementing RS-232 devices, you need to understand what modems did at a specific point in history.

I think the history of modems might usefully be broken into the following phases (note: Dates are extremely approximate. I think US technology is most relevant here, so I'm going to focus on that, even though I am not based in the US):

  • The half-duplex era (1950s and beyond): RTS and CTS have their original meaning The first versions of RS-232 would have been designed to support half-duplex modems. I haven't been able to find information about these, but it does seem that they were not used on the (US) telephone network; all commercially available modems for the public telephone network were full-duplex devices. However I think that this style of modem took a very long time to fully die out, if they ever did; instead they they were just relegated to niches like radio. This is where the original meaning of RTS and CTS come from. Because only one side could be talking at a time, you would have to request the medium, and then wait for it to become available. RTS (Request to Send) was the "I want to take control of the medium" signal, and CTS (Clear to Send) was the "You have control of the medium" signal. These two lines seem to often have been called "the modem control lines", and that is what they were for: controlling the modem, not flow control. I am unclear as to which of the other handshaking lines would have been used by these devices. However I suspect that at least DSR was not.
  • Bell 103 and 212 compatibles (1970s and 1980s): RTS and CTS are obsolete? The first commercially available modem in the US was the Bell 103, which was pretty rare, but a lot of devices were eventually introduced that was compatible with it. This excellent video shows what these modems were like. Internally they were relatively simple. As they were full duplex devices without any internal buffering, it would have been necessary to configure the serial link to match the baud rate of the modem (300 or 1200 baud). This period would have been the heyday of devices like serial printers, serial plotters and serial terminals, which could easily have been connected to a remote computer through one of these modems. Devices and software designed in this period would have probably supported using the modem control signals (with their then-current meanings) as half-duplex devices were probably still around, but this "modem mode" was likely to be optional even if you were using a modem. Once these modems were connected, there would be no need to assert RTS or wait for CTS; it should have been possible to use one of these devices with a 3-wire serial cable. Adding the DTR, DSR and DCD signals would enable you to know if the modem was on, connected and enable automatic hang-up. RTS would either have been disconnected and ignored, or looped back to CTS, which would otherwise be linked to DSR.
  • Smart-modems accelerate (1980s): CTS returns as flow control The Hayes Smartmodem, and the myriad similar devices introduced automatic dialling, and with it an internal microprocessor and command language. Significantly this enabled modems to have internal buffers, which meant that it would now be productive to configure the serial link at higher than the modem speed. A lump of data could be sent to the modem, which could then be gradually sent out at the speed of the connection. The DTE would not even need to know how fast the connection was, and automatic negotiation became possible! However this meant that flow-control would be necessary. Happily the CTS signal would work fine for this; systems designed to be aware of half-duplex modems would not send data while CTS was not asserted, and systems not aware of CTS shouldn't be sending fast enough to overflow the buffer so this is a backwards compatible change. Data rates increased towards 9,600 baud through the 1980s.
  • 9.6Kbps and up, e.g. (late 1980s, to 2000s): RTS returns with a new meaning In this period the speed of the serial link between your computer and your modem finally became important, as modems were fast enough that old PCs with crummy UARTS wouldn't be able to keep up with their modems. As the RTS line had been irrelevant for some time, but would usually be connected in a modem cable, modems optionally started to support repurposing it to enable hardware flow control from the modem to the computer - which modems hadn't supported until now.

So in the period when I think DTR or DTR/DTS flow-control became common, there was an understanding that the RTS and CTS lines had a meaning - the meaning it had for half-duplex CTEs - but at the same time RTS and CTE might have been absent from any given serial cable, and ignored by any computer as it wasn't relevant to contemporary modems.

I/O devices of the '80s needed flow control before computers did

While I presume that almost any computer was faster than the modem or peripherals it was connected to, lots of devices like plotters or printers would have occasionally been overwhelmed even at 1,200 baud (I think smart terminals might keep up at these rates though). These devices were implemented as DTEs, meaning that they could be connected to a modem, or to another DTE through a null-modem cable. RS-232 had no standard way of providing out-of-band flow control for DTEs.

Aside: xon/xoff flow control might have worked better than you'd think

We're used to describing xon/xoff flow-control as software flow-control, and we're often warned that it does a poor job of flow-control and causes data corruption. It had one job, but failed twice.

The reason xon/xoff flow-control can cause data-corruption is that it uses two bytes (typically 0x13 and 0x11, but often configurable) in-band in the communication streams to signal that a buffer is becoming full, and sending should be slowed or stopped until it's sorted out. These bytes are not processed with the rest of the data stream. But if the data you are transmitting happens to contain either of these bytes, well you've halted the flow of data, and that byte gets removed from the transfer. That means it's manifestly unsuitable for transferring arbitrary binary data. However many of the peripherals we're describing are character devices, and so these two bytes should usually be perfectly safe. When terminals use xon/xoff flow-control Emacs users are prone to complain that Control-Q and Control-S don't work.

The reason xon/xoff is considered slow is because it is often handled in software. On PCs in particular, systems started using UART chips with increasingly large buffers, and only reading the input data once they had been filled, which could be after many bytes had been received, and long after the xoff byte had been sent. However, in researching this I've seen references to mini-computers or servers having hardware accelerated console ports, which would handle the processing of xon/xoff bytes automatically, and as they arrive. So if the remote machine is properly equipped xon/xoff should have worked well in that respect too.

It seems that at least some modern USB to RS-232 adaptor chips also do automatic handling of xon/xoff and that this is supported by Linux².

Hardware flow-control makes no sense on the modems of the era, but DTR flow-control would not have been very compatible with them

I suspect (but have no proof) that DTR/DTS flow-control was not ever supported by modems. But the for the modems that were in use at the time, it would not have helped. Even if the modem had a buffer (which it probably didn't), then it would have been tiny, and telling the the modem to stop sending data would just have led to the buffer in the modem overflowing, instead of the one in the device. However these dumb modems would have been transparent to xon/xoff bytes, and so they would have had the effect of telling the sending system to slow down, which hopefully would have the desired effect.

Dropping the DTR signal on a DTE connected to a modem has the potential to make it drop the connection. This was an optional feature that could be disabled (local laws not withstanding).

Overall enabling DTR or DTR/DSR flow-control on a device connected to a modem is likely to create more problems than it solves.

DTR/DTS flow-control does make sense on null-modems of the era

However if the device is connected to another DTR directly through a null-modem cable, it's likely that the serial link is going to be very much faster, and even terminals are prone to be overwhelmed. And as xon/xoff flow-control can have problems for terminals, and software implementations have issues, it makes sense to make a non-standard but optional, and pretty compatible extension to the standard (just as the modem manufacturers would also do).

It stands to reason that you shouldn't send data to a device that is not ready - and so turning off the the Data Terminal Ready signal when your buffer is full makes sense. And in terms of sending it makes sense not to send data to a Dataset which is not ready, so using the DSR signal for the other direction makes sense too. It was already common practice for these two signals to be crossed in the numerous null-modem wirings of the era. If a device configured for DTR/DTS were connected to a fast modem, these could potentially cause a connection to be dropped - but only if that feature is enabled on the modem.

MS DOS did support DTR/DTS flow-control (Perhaps)

I have no evidence whatsoever for this other than some vague things I saw, I cannot find a source that tells me one way or the other, or when it was introduced, and I'm not equipped to check for myself. I do believe that modern Windows supports it based on the online help.

The MS DOS MODE command provides the means to enable DTR/DTS handshaking.

Some Unix vendors supported DTS/DTR flow control

POSIX appears to be silent on what hardware flow-control should be supported on Unix. It would be surprising if it were not. The Linux man page for termios.h notes that CRTSCTS (which is the option passed to enable RTS/CTS hardware flow control on an interface) is not in POSIX. Sure enough, the version published by The Open Group does not include either CRTSCTS or CDTSDTR. The (much more detailed) equivalent for FreeBSD includes CRTSCTS (but doesn't say if it's standard). The Open Group header file does not include it.

However the MacOS implementation of that header does include constants for DTR and DTS hardware overflow - whether that is supported by the OS, or this is vestigial, I'm not able to say.

Apparently System V did seem to have supported DTR/DTS flow control. The equivalent constants were defined in termiox.h. This is the documentation for AIX. However surprisingly, Ultrix and HP/UX do not seem to support it.

Is it true that Linux does not support DTR/DTS flow control?

A premise of the question is that Linux does not have support for DTR/DTS flow control. This is only sort of true. It's possible to write userspace code that reads the state of the various serial port control lines, and sends data or waits, depending on what it finds. However RTS/CTS flow control is supported by the kernel, and can be enabled for a specific port, using the stty command. This is no doubt not only faster and easier, it's probably a lot more reliable. It also offers the possibility of taking advantage of features of the hardware to support it.

Linux partially added support for DTS/DTR flow control... but removed it

At one point a patch was included from Alan Cox to enable the System V style termiox interface. However the follow up work to connect this to the TTY and serial drivers seems to never have landed, and the support was later removed.


So it seems there have been (at least) two approaches to hardware flow-control in RS-232 devices, both were initially non-standard. Both were supported by various Unixes. Both saw use on the PC platform. The earlier one adopted by many DTE devices like printers and terminals was DTR/DSR - but it's not very compatible the meanings given to these signals by modems. RTS/CTS came later, but it undoubtedly became more widely deployed, and it became standardised in the early '90s.

Since Linux development started in the '90s, and devices implementing RTS/CTS flow control were already widespread (especially fast modems, and who doesn't want a fast modem?) it makes perfect sense that Linux would support this standard.

Non-modem RS-232 devices were unusual before long, and wiring null-modem cables to support old devices is usually possible, and I guess ultimately no one ever cared enough to support the other approach.

  1. Technically I should say RTR/CTS flow control, but every single source I've seen that mentions this distinction uses the word "technically".
  2. This is good news for me, as it turns out the eBay seller sent me 3-core cable not 5-core.
  • 2
    "most common use...have been modems" Perhaps also of note: That's the original use-case. The "DCE" in RS-232 standards stands for "Data Communication Equipment." That's a fancy way of saying "modem." The original purpose of RS-232 was to connect something* to a modem. [* The "something" is "DTE" or "Data Terminal Equipment" in the standard nomenclature. We called it that regardless of whether it was a computer terminal or if it was the computer itself.] Commented Nov 8, 2023 at 20:37
  • 1
    Yes, that's my understanding of the intent of RS-232 too. Although I must admit I haven't actually read any of the standards. Commented Nov 8, 2023 at 21:06
  • "MS-DOS" does not implement any kind of flow control, but the INT 17h (BIOS) interface used by MS-DOS does. The INT 17h flow control implementation is not disablable and unsuitable for null-modem connections. The DOS mode command has no setting to enable/disable flow control, but DOS can be toggled between "infinite retries" and "call INT24 critical error" in case of flow control timeout. (the ",p" at the end of the mode string configures infinite retries) Commented Nov 8, 2023 at 21:43
  • @MichaelKarcher thanks for that, I'll have a look into that. So if you redirect a file to COM1, for example, is that using those BIOS routines? What is/was available in the MODE command in MS-DOS? Commented Nov 8, 2023 at 21:50
  • @MichaelKarcher Am I right in thinking that the default BIOS behaviour is to use xon/xoff? Commented Nov 8, 2023 at 21:58

As a rather old dinosaur (older than 60...) I can remember using V23 modems in the 80's. They were rather popular in France because they were the modem of the good old minitel. In short it was a packed 40x25 screen, keyboard and V23 modem, freely distributed by the French public telecom service. Before PC became common, it allowed anyone to access train and plane reservation, consult weather services, etc...

The V23 modem was a half-duplex system operating at 1200 bauds (~ bits/second), with an optional backward channel operating at 75 bauds (yes only 75!). In raw half duplex mode, the DTS/DTR handshake was normaly used to indicate that the DTE and DCE were active.

To send a message, the DTE used the RTS signal. The modem established its carrier and set the CTS signal when it was ready to send data.

To receive the response, the DTE had to lower the RTS signal. The modem in turn lowered its CTS, drop its carrier and put itself in receiving mode. It then used the Carrier Detect signal to tell the DTE that it could listen to the received data.

For that reason, it did make sense to stop sending anything until the CTS signal was set. As Unix began in the 70's, half duplex modem were still a thing and RTS/CTS had to be supported.


The assumption in the question is incorrect. Linux has support for modem control lines like DSR and DTR, via the TIOCMGET and TIOCMSET TTY ioctl command.

The relevant bitmask values are TIOCM_DSR and TIOCM_DTR.

The pattern I'm seeing across all the myriad serial drivers is that TIOCM_DTR is both read and write, whereas TIOCM_DSR is read only (the hardware's status will be shown, but cannot be set). I.e. Linux wants to play only the DT role.

The higher level function tty_tiocmset in fact masks out a certain allowed subset that are writable, where the last part of the dispatch code looks like:

    return tty->ops->tiocmset(tty, set, clear);

I don't see any implementation of flow control in the kernel based on these signals. It's something that should be fairly easy to hack, and with the above ioctl, should be doable from user space. The application reading from the TTY file descriptor can keep TIOCM_DTR de-asserted while it's not reading, and likewise monitor for TIOCM_DSR being down, and refrain from writing.

The main issue is that CTS-RTS handshaking is low-level and handled by individual drivers. Some hardware, like certain Texas Instruments 16550 UARTS, has it implemented in hardware. When the CTSRTS flag is enabled on the TTY descriptor via tcsetattr, this is translated to some bit being set in the hardware to turn that on.

I suspect it's uncommon for serial hardware to support a similar thing for DSR and DTR, because those are not lines intended for flow control.

A DSR/DTR handshaking state machine could perhaps be implemented in the TTY layer above the drivers. We would have to invent a new termios bit for it, some #define CDSRDTR symbol using an available bitmask value. The TTY code would see this and monitor the low level driver's DSR before sending, and de-assert DTR when buffers are close to full, using the get_mctrl and set_mctrl virtual functions of the serial driver.

I should mention that there is a dtr_rts virtual function in a struct tty_port_ops. Some drivers implement this, but it looks like not all. The purpose of this function is to raise the DTR and RTS lines when a port is opened or deassert them when it's closed.

DTR and DSR don't mean ready for the next byte, but ready as such, online.

Some modems can be configured such that they raise the DSR signal when there is an active call. Then when the call hangs up, DSR is de-asserted. This can be used by the host to clean up the TTY session: generate the SIGHUP signal, etc.

Imagine you have a dial-up modem connected to a Unix-like host, and there is no DTR/DSR signaling. If are abruptly disconnected while logged in, and someone else dials in, they get to hijack your shell session.

  • Indeed a program can set the DTR and RTS lines manually so driver or hardware does not handle the flow control but software itself. But if you tell the driver to automatically handle flow control, there is only RTS/CTS handling by the driver. And contrary to your answer, since 16550 does not support hardware flow control, the driver will anyway handle the RTS/CTS handshaking for you in software on a 16550. The question was about why the driver supports only automatic RTS/CTS flow control handshake in the driver but not DTR/DSR flow control handshake.
    – Justme
    Commented Nov 10, 2023 at 5:34
  • @Justme Yes; what I was looking at is the use of this flag #define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */. It's a particular Texas Instruments 16550 which has the feature, and the driver uses it.
    – Kaz
    Commented Nov 10, 2023 at 6:25
  • So it's not a 16550 but a manufacturer specific 16550-compatible UART with enhanced features and deceivingly similar name. The original 16550 surely had no such feature.
    – Justme
    Commented Nov 10, 2023 at 6:52
  • While some modems surely can be configured to use DSR to indicate an active call, there is a different signal, CD aka DCD dedicated to this very purpose on full-duplex connections. Unless you actively set control flag local, the TTY driver will not allow communication before DCD is high and send a ´SIGHUP` signal as soon as DCD goes low. The more conventional use of DSR with 90s era PC modems in data mode is just to indicate that the modem is powered up. This might be different for half-duplex fax mode, as DCD on half-duplex means the remote side is currently transmitting. Commented Nov 10, 2023 at 7:35
  • @MichaelKarcher Ah, that jogs my memory quite a bit.
    – Kaz
    Commented Nov 10, 2023 at 7:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .