Implementing ‘noecho’ Programming details regarding the Linux implementation for ‘struct...
-
Upload
anthony-sims -
Category
Documents
-
view
213 -
download
0
Transcript of Implementing ‘noecho’ Programming details regarding the Linux implementation for ‘struct...
Implementing ‘noecho’
Programming details regarding the Linux implementation for
‘struct termios’ objects
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 );
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
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?
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
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
.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
system would overwite part of the next data-area
tcgetattr() does notknow the size thatwe have allocated
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?
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
The actual loop code
movl $origtty, %esimovl $worktty, %edimovl $60, %ecx
again: movb (%esi), %almovb %al, (%edi)incl %esiincl %ediloop again
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)
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 echoi.e., worktty.c_lflag &= ~ICANON;
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
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