File Handling in Linux 5


3. Terminal I/O

3.1 How can I make my program not echo input?

How can I make my program not echo input, like login does when asking for your password?
There is an easy way, and a slightly harder way:
The easy way, is to use getpass(), which is probably found on almost all Unices. It takes a string to use as a prompt. It will read up to an EOF or newline and returns a pointer to a static area of memory holding the string typed in.
The harder way is to use tcgetattr() and tcsetattr(), both use a struct termios to manipulate the terminal. The following two routines should allow echoing, and non-echoing mode.
#include <stdlib.h>
#include <stdio.h>
 
#include <termios.h>
#include <string.h>
 
static struct termios stored_settings;
 
void echo_off(void)
{
    struct termios new_settings;
    tcgetattr(0,&stored_settings);
    new_settings = stored_settings;
    new_settings.c_lflag &= (~ECHO);
    tcsetattr(0,TCSANOW,&new_settings);
    return;
}
 
void echo_on(void)
{
    tcsetattr(0,TCSANOW,&stored_settings);
    return;
}
Both routines used, are defined by the POSIX standard.

3.2 How can I read single characters from the terminal?

How can I read single characters from the terminal? My program is always waiting for the user to press RETURN.
Terminals are usually in canonical mode, where input is read in lines after it is edited. You may set this into non-canonical mode, where you set how many characters should be read before input is given to your program. You also may set the timer in non-canonical mode terminals to 0, this timer flushs your buffer at set intervals. By doing this, you can use getc() to grab the key pressed immediately by the user. We use tcgetattr() and tcsetattr() both of which are defined by POSIX to manipulate the termios structure.
#include <stdlib.h>
#include <stdio.h>
 
#include <termios.h>
#include <string.h>
 
static struct termios stored_settings;
 
void set_keypress(void)
{
    struct termios new_settings;
 
    tcgetattr(0,&stored_settings);
 
    new_settings = stored_settings;
 
    /* Disable canonical mode, and set buffer size to 1 byte */
    new_settings.c_lflag &= (~ICANON);
    new_settings.c_cc[VTIME] = 0;
    new_settings.c_cc[VMIN] = 1;
 
    tcsetattr(0,TCSANOW,&new_settings);
    return;
}
 
void reset_keypress(void)
{
    tcsetattr(0,TCSANOW,&stored_settings);
    return;
}

3.3 How can I check and see if a key was pressed?

How can I check and see if a key was pressed? On DOS I use the kbhit() function, but there doesn't seem to be an equivalent?
If you set the terminal to single-character mode (see previous answer), then (on most systems) you can use select() or poll() to test for readability.

3.4 How can I move the cursor around the screen?

How can I move the cursor around the screen? I want to do full screen editing without using curses.
Seriously, you probably don't want to do this. Curses knows about how to handle all sorts of oddities that different terminal types exhibit; while the termcap/terminfo data will tell you whether any given terminal type possesses any of these oddities, you will probably find that correctly handling all the combinations is a huge job.
However, if you insist on getting your hands dirty (so to speak), look into the termcap functions, particularly tputs(), tparm() and tgoto()



To Look for similar posts on File handling in Linux explore the following links from the same blog as well.
 
 

Post a Comment

Previous Post Next Post