1 / 14

Implementing ‘noecho’

This text provides details on implementing 'noecho' programming in Linux, specifically regarding the struct termios objects. It covers basic issues to consider, the algorithm for implementing 'noecho', storage space requirements, memory addressing, constants in assembly, copying a structure object, modifying flag bits, and non-canonical terminal modes. A suggested application of non-canonical mode is also mentioned.

Download Presentation

Implementing ‘noecho’

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Implementing ‘noecho’ Programming details regarding the Linux implementation for ‘struct termios’ objects

  2. Basic issues to consider • Normal tty operation is ‘canonical’ mode • Input gets processed one line at a time • Line-editing is allowed (e.g., backspace) • User’s keystrokes echoed to the screen • In C/C++ demo we could turn off echoing • We used two standard interface functions: • int tcgetattr( int fileno, struct termios *tty ); • Int tcsetattr( int fileno, int flag, struct termios *tty );

  3. Basic Algorithm • Save a copy of the initial terminal settings • Modify certain bits in the ‘c_lflag’ field: • Turn off the ECHO bit, and • Turn on the ECHONL bit • Install the modified terminal settings • Perform desired echo-free keyboard input • Then reinstall the original terminal settings

  4. How much storage space? • We must reserve adequate space for storing the initial terminal settings • But we don’t know how big this object is • This issue was transparently handled for us in our ‘noecho.cpp” demo by including: • #include <termios.h> • struct termios save_termios; • How can we accomplish this in assembly?

  5. The ‘c_lflag’ field • We needed to modify bits in ‘c_lflag’ field • Those bits were represented by constants: ECHO and ECHONL • Their values were defined in <termios.h> • We did not need to know the actual values • But header-file isn’t available in assembly • So now we do need to know these values • Another constant needed is TCSANOW

  6. Memory addressing • Where’s ‘c_lflag’ field within termios object • We can’t modify its bits until we know that • One idea is to study the Linux header-file • But where is it? There seem to be several • Nested type-declarations add to confusion • Another approach: let’s write a program to report the specific information we’ll need • Our ‘ttyinfo.cpp’ demo program shows us that sizeof( struct termios ) equals 60 bytes

  7. .section .data # we need storage for two ‘termios’ objects origtty: .space 60 # original settings worktty: .space 60 # a ‘working copy’ # Insufficient space would cause big trouble! origtty worktty tcgetattr() does not know the size that we have allocated system would overwite part of the next data-area

  8. Constants in assembly • We can use the .equ directive to create our own manifest constants: .equ ECHO, 0x00000008 .equ ECHONL, 0x00000040 .equ TCSANOW, 0x00000000 • Question: will our program also work on other versions of UNIX besides Linux?

  9. Copying a structure object • We can create a program loop to copy the contents of a data-structure • Here again we need to know the number of bytes in the structure we want to copy • We can use a ‘counted loop’ to do copying • Three initialization steps: • put source-address in register %esi • put dest’n address in register %edi • put the byte-count into register %ecx • Advance %esi and %edi as each byte is copied

  10. The actual loop code movl $origtty, %esi movl $worktty, %edi movl $60, %ecx again: movb (%esi), %al movb %al, (%edi) incl %esi incl %edi loop again

  11. Modifying some flag bits • Determine offset of the ‘c_lflag’ field (=12) • Setup this offset in a CPU register (%edi) movl $12, %edi • Use AND-instruction to turn a bit off: andl $~ECHO, worktty(%edi) • Use OR-instruction to turn a bit on: orl $ECHONL, worktty(%edi) • (Here other approaches also are possible)

  12. Non-canonical terminal modes • Certain kinds of applications do not lend themselves to ‘canonical’ terminal input • We may want an instant response to each individual keystroke (not to an entire line) • Example: computer game using keyboard • We can ‘turn off’ canonical line-processing • Very similar to ‘turning off’ the input echo i.e., worktty.c_lflag &= ~ICANON;

  13. Two further adjustments • Need two changes in the c_cc[] array: worktty.c_cc[ VMIN ] = 1; worktty.c_cc[ VTIME ] = 0; • First change causes ‘read()’ function to return as soon as at least one character has been typed • Second change causes ‘read() function to return without any time-delay

  14. An application • You could use this ‘non-canonical’ terminal mode to implement visual “user feedback” in your ‘password’ program • Whenever the user presses a new key, the program immediately responds by printing a neutral character (e.g. ‘*’) to confirm that it has indeed received the user’s input • Special handling for ‘backspace’ is needed • Suggestion: Try it first in a C/C++ program

More Related