| |
Line Discipline Design NoteThis is a proposed design of the line discipline for EROS, the Extremely Reliable Operating System. Basic Ideas (introduction?)In this design, we view the Line Discipline as a "filtering" module which sits between a Character Source, which provides both a source of characters to process and a sink for writing output to. In this view, there are two "sides" to the line discipline interface: - The interface the client sees, and
- the interface to the character source (i.e. serial device, console, etc) that the line discipline gets the characters it processes from.
This design note covers the requirements and design of both of these interfaces.Prevailing AssumptionsThis design was done with a few assumptions and biases: - Parts of the Unix termios functionality was used as both a guideline to what basic functionality is needed in a line discipline. The Unix termios facility as a whole is also used as an example of something which is going to have to be emulated as a client of the line discipline.
- others ...
RequirementsLine Discipline RequirementsThere are a few requirements we saw as important in the design of the EROS line discipline: - Speed -- the line discipline should not have a large processing overhead
- The Line Discipline should provide basic erase processing, including character, "word", and line erase.
- The line discipline should provide a way to select what input and output processing is desired, including:
- Whether or not to do erase processing
- the presence of "stop" characters (i.e. characters whose reciept causes immediate notification)
- Whether or not to echo entered characters
- etc.
These should be independently selectable. - The ability to pass on some control information to the character source
There were some other requirements that we felt were not the job of the EROS line discipline:- Multiplexed input and output -- The EROS line discipline only supports a single reader/writer/controller.
Character Source RequirementsCharacter sources generate and accept characters. Some examples of character sources are: - Terminal devices
- The console in text mode
- Telnet/rlogin sessions.
The general requirements for the character source interface are:- Early termination of blocked requests -- There has to be a way for a blocked request to return before being completely fulfilled. (i.e. timeouts, "stop" characters, etc)
- There should be a generic way to control the character source.
- The interface must be implementable in a kernel key.
InterfaceCharacter Source InterfaceOperationsThe Character Source Interface consists of four operations: | Operation | Description | | OC_CharSrc_Write | A Write is a non-blocking call which consists of a text message containing the characters to write. The character source attempts to write as many characters as it can without blocking. It returns RC_OK when done, with a count of how many characters were successfully written. If the character source's write buffer fills (i.e. it wrote less than you asked it to write), a CharSrc_WriteSpaceAvailEvent event will be posted when it has partially emptied. | | OC_CharSrc_WaitForEvent | A WaitForEvent call consists of a message with a maximum read count and an event mask. If any of the events in the event mask have already fired, the call returns immediately. Otherwise, the call blocks, waiting for an event in the event mask to fire. There can be a maximum of one reader blocked on each Character Source. On success, returns RC_OK, the events which have fired, and any characters recieved, up to the number requested. Returns RC_CharSrc_OneWaiterOnly if there is already someone waiting on this Character Source. | | OC_CharSrc_PostEvent | A PostEvent call consists of an event mask, which must only consist of user-defined events. The effect is to fire the events specified. The main use of this call is to notify a thread blocked on WaitForEvent that something requires its attention. Returns RC_OK on success, RC_RequestError if the event mask contains non-user events. | | OC_CharSrc_Control | A Control call consists of a ControlMessageType plus additional arguments, whose interpretation depends on the ControlMessageType. Some specific control messages must be implemented as part of the character source interface, and the rest can be used for device-specific status and control messages. Returns RC_OK on success, with additional data dependent upon the ControlMessageType. |
EventsThe interface defines the following events: | Event | Description | | CharSrc_FilledBufferEvent | Fired when the number of characters recieved reaches the minimum of the number of characters asked for and the maximum buffer size of the Character Source. | | CharSrc_TimeOutEvent | Fired when the timeout parameters have been reached. (see TimeoutControl, below) | | CharSrc_SpecialCharEvent | Fired when a special character is recieved. (see SpecialCharactersControl, below) | | CharSrc_WriteSpaceAvailEvent | Fired when the character source, after refusing to accept some characters in a Write call, is able to accept more characters. | CharSrc_UserEvent0 through CharSrc_UserEvent7 | Eight distict events that are only fired when posted using PostEvent. These are used to wake up the person waiting for an event when necessary. |
Control MessagesThe interface defines the following control messages: | Control Message Type | Description | | CharSrc_Control_SetTimeout | Uses the two register arguments. The first argument, InitialChars is the number of initial characters to be recieved before the timeout begins. (usually 1) The second argument, Timeout, is the length of the timeout, in milliseconds. A Timeout of zero means an immediate return after InitialChars characters have been read. (This could be useful if you wanted to have characters returned as they were typed, but also take advantage of any buffering that occurred). A Timeout of WORD_MAX disables the timeout mechanism. The TimeOutEvent will be fired at least Timeout milliseconds after InitialChars have been received. The timeout is turned off after a successful WaitForEvents call has completed. | | CharSrc_Control_GetTimeout | Returns the current Timeout parameters in two register arguments. | | CharSrc_Control_SetSpecialCharacters | Uses a string argument. The string is a series of 2-byte characters (Unicode) which should be recognized as Special Characters. No characters not included in the string will be considered Special Characters. The SpecialCharEvent will be fired immediately upon reciept of any special character. The special character is inserted into the received character buffer. Returns RC_OK on success, RC_RequestError if either too many special characters were sent or an unsupported character was sent. (i.e. a non-ASCII Unicode character for an ASCII-based device) If the call fails, the special characters remain unchanged.. | | CharSrc_Control_GetSpecialCharacters | Returns the current special characters as a series of two-byte characters in a string. The special characters may be in any order. |
Line Discipline InterfaceThe Line Discipline follows the Character Source Protocol outlined above. It acts as a "filter", taking in and writing out characters to a "background" character source which is passed in during initialization. The Line Discipline module handles such things as echo processing, erase processing, etc. The controls for the line discipline are implemented as additional ControlMessages. Modes of the Line DisciplineThe LineDiscipline interface has two main modes: | Mode | Description | | Raw Mode | Raw mode acts exactly like a standard Character Source module, except that basic input and output processing (like echoing) can be enabled. | | Line Mode | When in Line Mode, the Line Discipline acts a bit differently from a standard Character Source. First, no data is returned to the reader until either a Special character appears or the Line Discipline's buffer fills. In particular, the timeout parameters only effect the speed of the LineDiscipline's response to its input. In fact, the timeout event will *never* be sent to the reader while in Line Mode. Also, UserEvents will not cause any data to be returned. |
Line Discipline Control MessagesThe line discipline has the following additional control messages: | Control Message | Description | | LineDisc_Control_SetInpProcessing | Takes a Word of input processing flags. Sets the input processing to follow the new flags. | | LineDisc_Control_GetInpProcessing | Returns a Word containing the current input processing flags. | | LineDisc_Control_SetOutpProcessing | Takes a Word of Output processing flags. Sets the output processing to follow the new flags. | | LineDisc_Control_GetOutpProcessing | Returns a Word containing the current output processing flags. | | LineDisc_Control_SetControlChars | Takes a String containing two-byte Unicode codes for the Control characters. Each control character should be placed at the position defined by its LD_CC_* macro. A zero character should be in any disabled CC slot. The String should be 2*LD_Num_CC bytes long. See Control Characters for more details. | | LineDisc_Control_GetControlChars | Returns a string in the exact form of SetControlChars. |
Processing flags| Flag Name | Description | | LD_In_DoInpProc | Enables input processing -- if not set, all other input flags are effectively clear. | | LD_In_LineMode | Enables Line Mode. If not set, the Line Discipline is in Raw Mode. | | LD_In_Echo | Enables Echo processing. If set, all characters recieved are echoed back on the write channel. | | LD_In_EchoCtrl | This flag has no effect if LD_In_Echo is not set. If this is set, all control characters but TAB, CR, and NL are echoed as^C(where C is @ + the ASCII code of the control character). If this is not set, they are echoed back verbatim. | | LD_In_AlwEchoNL | If set, NewLines are echoed regardless of LD_In_Echo. | | LD_In_VisErase | If set, when an Erase/EraseWord control character is processed, the preceeding character/word is visually wiped out. If not set, the erase character is echoed. If LD_In_LineMode is not set, this flag has no effect. | | LD_In_VisKill | If set, when the KillLine control character is processed, the preceeding Line is visually wiped out. If not set, the KillLine character is echoed. If LD_In_LineMode is not set, this flag has no effect. | | LD_In_SoftFlow | Enables Software Flow Control on input | | LD_In_SwapCRNL | If set, Carriage return and newline are swapped before any other input processing is done (i.e. before Echo processing) |
| Flag Name | Description | | LD_Out_DoOutpProc | Enables output processing -- if not set, all other output flags are effectively clear. | | LD_Out_NLtoCR | Enables translation of NL->CR. (The CR resulting from this transformation will not be transformed back to NL by LD_Out_CRtoNL) | | LD_Out_NLtoCRNL | Enables translation of NewLines to CarriageReturn-NewLine. | | LD_Out_CRtoNL | Enables translation of CR->NL (if LD_Out_NLtoCRNL is set, CR->CRNL) |
Note: Control characters are only recognized in Line Mode. Also note the absence of a "end-of-line" characters. Any character that should cause immediate return of the line should be set using CharSrc_Control_SetSpecialChars. If any of the Control characters are set as Special Characters, they will NOT cause the line to be returned. At least one character (i.e.^M(Carriage-Return)) should be set as a special character. If an Erase or WordKill is sent with a write since either the first character in the line was typed or the last Erase command, the effect is as if the Retype character had been hit, then the Erase/WordKill was hit. See Interrupted Line Processing for more details. If a control character is set to 0, it is disabled. (^@ cannot be a control character) The available control characters are: | Control Character | Def | Description | | LD_CC_Erase | ^H | Removes the preceeding character. If LD_In_VisErase is set, the preceeding character is visually wiped out. Otherwise, the Erase character is echoed to indicate a character has been erased. The Erase character has no effect at the beginning of the line. | | LD_CC_AltErase | DEL | Same effect as LD_CC_Erase. | | LD_CC_EraseWord | ^W | Removes all space characters at the end of the input, then all non-space characters up to the previous space character. If LD_In_VisErase is set, the "word" is visually wiped out. Otherwise, the KillWord character is echoed to indicate that a word has been killed. | | LD_CC_KillLine | ^U | Removes all characters in the curent line. If LD_In_VisKill is set, the line is visually wiped out. Otherwise, the KillLine character is echoed, then NL is echoed to go to the next line. The KillLine character has no effect at the beginning of the line. | | LD_CC_Reprint | ^R | Reprints the current input line. First, the Reprint character is echoed, a NL is echoed, then the entire input line is printed. | | LD_CC_Quote | ^V | The next character is accepted without processing. Not echoed. If the following character is a Special Character, it is treated as if it were a normal character. The Quote character does appear in the read string before the quoted character. | | LD_CC_SFStop | ^S | If LD_In_SoftFlow is set, halts output. Not echoed. | | LD_CC_SFStart | ^Q | If LD_In_SoftFlow is set, restarts output. If this is disabled (== 0), then ANY character will restart output. |
Line Discipline IssuesReferencesIn designing the Line Discipline and Character Source interfaces, the following sources were very helpful: - UNIX® System V Release 4 Interface Definition, Prentice Hall, Third Ed., Vol 1, Chapter 8, pp38-54.
- Goodheart, Berny and Cox, James, The Magic Garden Explained -- The Internals of UNIX® System V Release 4, Prentice Hall, pp502-516.
- UNIX® System V Release 4 Programmer's Guide: STREAMS, Prentice Hall, Chapter 12, pp1-11.
- ftp://ftp.openbsd.org/pub/OpenBSD/src/sys/kern/tty.c (OpenBSD's TTY line discipline code)
Copyright © 1997,1998 by Jonathan Adams. All rights reserved. For terms of redistribution, see the GNU General Public License. | |