Thursday, June 13, 2013

Changing Properties of Terminal / Console using termios

         Linux Devices are designed for interactive use, that means devices used both for input and for output. All the devices have a similar interface derived from the serial TeleType paper-display terminals and thus dubbed the tty interface. tty(TeleType) is a interface which is used to access serial terminals, consoles, xterms, network logins and many more.

        All tty manipulation can be done using termios structure and several functions which all are defined in <termios.h> header file. struct termios as follows.

struct termios
{
   tcflag_t c_iflag;         /* input mode flags */
   tcflag_t c_oflag;        /* output mode flags */
   tcflag_t c_cflag;         /* control mode flags */
   tcflag_t c_lflag;          /* local mode flags */
   cc_t c_line;                 /* line discipline */
   cc_t     c_cc[NCCS];   /* special characters */
}

c_iflag - determines how received characters are interpreted & processed
c_oflag - determines how your process writes to the tty are interpreted & processed
c_cflag - determines serial protocol characteristics of the devices
c_lflag - determines how characters are collected & processed before they are sent to output processing

The main two functions which are used to manipulate tty are
tcgetattr() - to get a device's current settings, modify those settings
tcsetattr() - to make the modify settings active

Now lets write a small program, where we can change the properties of our terminal / console pro-grammatically so that we can read a password without echoing it in console / terminal. To understand the code do not forget to read comments in the code.

// File Name: termios.c

 #include <stdio.h>
 #include <termios.h>
 #include <unistd.h>

 void main()
 {
    struct termios termios_temp, termios_orig;
    char pwdbuffer[1024];

    // getting and saving current termios settings
    tcgetattr(STDIN_FILENO, &termios_temp);
    termios_orig = termios_temp;

    // changing current termios settings, so that entered password can't be echoed
    termios_temp.c_lflag &= ~ECHO;
    termios_temp.c_lflag |=ECHONL;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_temp);
    printf("NOTE: termios settings changed, so entered pwd can't be echoed :-)\n");

    // checking that the settings took effect or not
    tcgetattr(STDIN_FILENO, &termios_temp);
    if(termios_temp.c_lflag & ECHO)
    {
        fprintf(stderr, "failed to turn off echo");
        // setting original termios settings
        tcsetattr(STDIN_FILENO, TCSANOW, &termios_orig);
    }
  
    // getting pasword and printing the password
    printf("Enter Password:");
    fflush(stdout);
    fgets(pwdbuffer, 1024, stdin);
    printf("Your Entered Password is: %s", pwdbuffer);
  
    // setting original termios settings
    tcsetattr(STDIN_FILENO, TCSANOW, &termios_orig);
    printf("NOTE: termios settings changed to original:-)\n");
}

To Run: gcc termios.c
              ./a.out

3 comments:

  1. Nice program.
    To simulate above situation utility in unix and liux stty.
    stty -echo is used to turn displaying user input through keyboard on the terminal.
    stty echo will enable the same.

    ReplyDelete
  2. Nice program.
    To simulate above situation there is one utility in unix and linux : stty.
    stty -echo is used to turn displaying user input through keyboard on the terminal.
    stty echo will enable the same.

    ReplyDelete
    Replies
    1. Thanks for your appreciation...stty works for unix / linux terminal only but the procedure which is used in above program can be used for any tty interfaces.

      Delete