终端结构体:
#define NCCS 19
Struct termios
{
tcflag_t c_iflag; /* input modes */
tcflag_t c_oflag; /* output modes */
tcflag_t c_cflag; /* control modes */
tcflag_t c_lflag; /* local modes */
cc_t c_line /*control line*/
cc_t c_cc[NCCS]; /* control chars */
}
每个终端对应这样的一个结构,结构中的标志集合控制着终端接口的各种特性. 在POSIX中定义了访问Struct termios 的方法:
#include <termios.h>
int tcgetattr(int fd, structtermios *tptr);
int tcsetattr(int fd, int action, struct termios);
action可能的含义是:
TCSANOW: 立即填入终端结构
TCSADRAIN: 如果当前缓冲区有数据,将在这些数据送入终端后才填充结构
TCSAFLUSH: 放弃当前缓冲区中的数据
示例:
/*AskTerminal.c*/
#include <termios.h>
#include <stdio.h>
#include <sys/signal.h>
#include <stdlib.h>
struct termios old_save;
int standard_fd = 0;
void error_quit(char * error_str);
/*print message*/
void error_quit(char * error_str)
{
fprintf(stderr,"%s/n",error_str);
exit(1);
}
/*change terminal attributes*/
void change_mode(void)
{
struct termios new_term;
//if is a terminal
if (!isatty(standard_fd)) //检验与standard_fd相连的是不是一个打开的终端
error_quit("standard input is not a terminal./n");
if (tcgetattr(standard_fd,&new_term) == -1)
error_quit("get the attribute of the terminal./n");
old_save= new_term;
new_term.c_lflag &= ~ISIG;
if (tcsetattr(standard_fd,TCSANOW,&new_term) == -1)
error_quit("set new terminal attributes./n");
}
/*restore terminal attributes*/
void restore_mode(void)
{
if (tcsetattr(standard_fd,TCSANOW,&old_save) == -1)
error_quit("restore ternimal attrivutes./n");
}
/*action handle function*/
void handle_ctrl_c(int signo)
{
printf("The process receive SIGINT, signal number = %d/n",signo);
printf("Now The process will change its ternimal attributes./n");
change_mode();
}
/*action handle function*/
void handle_term_signal(int signo)
{
printf("The process receive SIGTERM, signal number = %d/n",signo);
printf("Now The process will restore attributes./n");
restore_mode();
exit(0);
}
/*main method*/
int main(int argc,char ** argv)
{
signal(SIGINT,handle_ctrl_c);
signal(SIGTERM,handle_term_signal);
printf("Please press the buttons CTRL + C/n");
for (;;);
}
运行程序后,按CTRL+C,显示:
The process receive SIGTERM, signal number =2
Now The process will restore attributes.
再按CTRL+C 则没反应, 从另一个terminal窗口中用 ps -ef|grep AskTerminal, 查得AskTerminal进程标识符,设为 333, 用 kill -15 333 发出 SIGTERM 信号, 则进程退出.