在我们编写程序的时候,有的时候需要输入密码,但是输入的密码全部是可见的,我们可以设置关闭终端回显不让终端显示字符。
取消终端输入回显主要由termios结构实现,
#include <stdio.h>
#include <termios.h>
int main(){
structtermiosnew_setting,init_setting;
charpwd[16];
tcgetattr(0,&init_setting);
new_setting=init_setting;
//get termios setting and save it
new_setting.c_lflag&=~ECHO;
tcsetattr(0,TCSANOW,&new_setting);
printf("please enter password: \n");
fgets(pwd,sizeof(pwd),stdin);
printf("you enter %s\n",pwd);
//restore the setting
tcsetattr(0,TCSANOW,&init_setting);
return 0;
}
取消回显是对终端的一种操作,而终端的值操作主要包含在如下的结构体里。
#include <termios.h>
structtermios{
tcflag_tc_iflag;
tcflag_tc_oflag;
tcflag_tc_cflag;
tcflag_tc_lflag;
cc_tc_cc[NCCS];
};
其中c_iflag控制输入数据在被传递给程序之前的处理方式。
c_oflag控制发送出去的字符传递到屏幕前是如何处理的。
c_cflag控制终端的硬件特性。
c_lflag控制终端的各种特性,上例取消回显正是对该项的一个操作。
c_cc对用户输入的CTRL+C这样的组合键时采取的一种特殊处理方式。
如果不是一定要编程实现取消回显,在终端输入stty -echo就取消了回显,stty echo可以恢复回显。
例子中通过inttcgetattr(intfg,structtermios *termios_p);获得初始化当前终端的termios结构,经过改变后调用inttcsetattr(intfg,intactions,conststructtermios *termios_p)保存改变的结果。
actions项的TCSANOW表示立即对变量的值进行修改。还有TCSADRAIN表示等终端的输出都完成后才进行修改。TCSAFLUSH和TCSADRAIN类似,但是丢弃还未从read调用返回的当前可用输入。
new_setting.c_lflag&=~ECHO;就是去掉回显的功能。
此外还有这些标志常量:
ISIG
当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号。
ICANON
启用标准模式 (canonical mode)。允许使用特殊字符 EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的缓冲。
XCASE
(不属于 POSIX; Linux 下不被支持) 如果同时设置了 ICANON,终端只有大写。输入被转换为小写,除了以 \ 前缀的字符。输出时,大写字符被前缀 \,小写字符被转换成大写。
ECHO
回显输入字符。
ECHOE
如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词。
ECHOK
如果同时设置了 ICANON,字符 KILL 删除当前行。
ECHONL
如果同时设置了 ICANON,回显字符 NL,即使没有设置 ECHO。
ECHOCTL
(不属于 POSIX) 如果同时设置了 ECHO,除了 TAB, NL, START, 和 STOP 之外的 ASCII控制信号被回显为 ^X, 这里 X 是比控制信号大 0x40 的 ASCII 码。例如,字符 0x08 (BS) 被回显为 ^H。
ECHOPRT
(不属于 POSIX) 如果同时设置了 ICANON 和 IECHO,字符在删除的同时被打印。
ECHOKE
(不属于 POSIX) 如果同时设置了 ICANON,回显KILL 时将删除一行中的每个字符,如同指定了 ECHOE 和 ECHOPRT 一样。
DEFECHO
(不属于 POSIX) 只在一个进程读的时候回显。
FLUSHO
(不属于 POSIX; Linux 下不被支持) 输出被刷新。这个标志可以通过键入字符DISCARD来开关。
NOFLSH
禁止在产生 SIGINT, SIGQUIT 和 SIGSUSP 信号时刷新输入和输出队列。
TOSTOP
向试图写控制终端的后台进程组发送 SIGTTOU 信号。
PENDIN
(不属于 POSIX; Linux 下不被支持) 在读入下一个字符时,输入队列中所有字符被重新输出。(bash 用它来处理typeahead)
IEXTEN
启用实现自定义的输入处理。这个标志必须与 ICANON 同时使用,才能解释特殊字符 EOL2,LNEXT,REPRINT 和 WERASE,IUCLC 标志才有效。
c_cc数组定义了特殊的控制字符。符号下标 (初始值) 和意义为:
VINTR
(003, ETX, Ctrl-C, or also 0177, DEL, rubout) 中断字符。发出 SIGINT 信号。当设置 ISIG 时可被识别,不再作为输入传递。
VQUIT
(034, FS, Ctrl-\) 退出字符。发出 SIGQUIT 信号。当设置 ISIG 时可被识别,不再作为输入传递。
VERASE
(0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) 删除字符。删除上一个还没有删掉的字符,但不删除上一个 EOF 或行首。当设置 ICANON 时可被识别,不再作为输入传递。
VKILL
(025, NAK, Ctrl-U, or Ctrl-X, or also @) 终止字符。删除自上一个 EOF 或行首以来的输入。当设置 ICANON 时可被识别,不再作为输入传递。
VEOF
(004, EOT, Ctrl-D) 文件尾字符。更精确地说,这个字符使得tty缓冲中的内容被送到等待输入的用户程序中,而不必等到 EOL。如果它是一行的第一个字符,那么用户程序的 read() 将返回 0,指示读到了 EOF。当设置 ICANON 时可被识别,不再作为输入传递。
VMIN
非 canonical 模式读的最小字符数。
VEOL
(0, NUL) 附加的行尾字符。当设置 ICANON 时可被识别。
VTIME
非 canonical 模式读时的延时,以十分之一秒为单位。
VEOL2
(not in POSIX; 0, NUL) 另一个行尾字符。当设置 ICANON 时可被识别。
VSWTCH
(not in POSIX; not supported under Linux; 0, NUL) 开关字符。(只为shl所用。)
VSTART
(021, DC1, Ctrl-Q) 开始字符。重新开始被 Stop 字符中止的输出。当设置 IXON 时可被识别,不再作为输入传递。
VSTOP
(023, DC3, Ctrl-S) 停止字符。停止输出,直到键入 Start 字符。当设置 IXON 时可被识别,不再作为输入传递。
VSUSP
(032, SUB, Ctrl-Z) 挂起字符。发送 SIGTSTP 信号。当设置 ISIG 时可被识别,不再作为输入传递。