unix/linux编程实践教程:学习stty

1. 终端实际上就是一个文件:

leichaojian@ThinkPad-T430i:~$ tty
/dev/pts/0
leichaojian@ThinkPad-T430i:~$ who > /dev/pts/0
leichaojian :0           2014-08-28 19:54 (:0)
leichaojian pts/0        2014-08-28 20:17 (:0)
leichaojian@ThinkPad-T430i:~$ ll /dev/pts/0
crw--w---- 1 leichaojian tty 136, 0  8月 28 20:38 /dev/pts/0

    常用的磁盘文件由字节组成,磁盘文件中的字节数就是文件的大小。设备文件是链接,而不是容器。设备文件的i-结点存储的是指向内核子程序的指针,而不是文件的大小和存储列表。内核种传输设备数据的子程序被称为设备驱动程序。

    对于tty,136和0被称为设备的主设备号和从设备号。主设备号确定处理该设备实际的子程序,而从设备号被作为参数传输到该子程序。


2. 终端驱动程序的模式

#include <stdio.h>
#include <ctype.h>

int main()
{
        int c;
        while ( ( c = getchar() ) != EOF ){
                if ( c == 'z' )
                        c = 'a';
                else if ( islower( c ) )
                        c++;
                putchar( c );
        }
}
    正常程序运行如下:

leichaojian@ThinkPad-T430i:~$ vim rotate.c
leichaojian@ThinkPad-T430i:~$ cc rotate.c
leichaojian@ThinkPad-T430i:~$ ./a.out
ab<-cd
bc<-de
efg^C

    但是,我们使用stty -icanon关闭了驱动程序中的规范模式处理,这时候并没有缓冲,所以输入后马上会显示结果:

leichaojian@ThinkPad-T430i:~$ stty -icanon; ./a.out
abbcxycdde

effggh^C
leichaojian@ThinkPad-T430i:~$ stty icanon
leichaojian@ThinkPad-T430i:~$ ./a.out
abcdef
bcdefg
^C


3. 使用非阻塞模式实现超时响应

#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>

#define ASK "do you want another transaction"
#define TRIES 3
#define SLEEPTIME 2
#define BEEP putchar('\a')

int main()
{
	int	response;
	tty_mode( 0 );
	set_cr_noecho_mode();
	set_nodelay_mode();
	response = get_response( ASK, TRIES );
	tty_mode( 1 );
	return response;
}

int get_response( char *question, int maxtries)
{
	int	input;
	printf("%s(y/n)?", question );
	fflush( stdout );
	while ( 1 ){
		sleep( SLEEPTIME );
		input = tolower( get_ok_char() );
		if ( input == 'y' )
			return 0;
		if ( input == 'n' )
			return 1;
		if ( maxtries-- == 0 )
			return 2;
		BEEP;
	}
}

int get_ok_char()
{
	int c;
	while ( ( c = getchar() ) != EOF && strchr( "yYnN", c ) == NULL )
		;
	return c;
}

set_cr_noecho_mode()
{
	struct termios ttystate;
	tcgetattr( 0, &ttystate );
	ttystate.c_lflag &= ~ICANON;
	ttystate.c_lflag &= ~ECHO;
	ttystate.c_cc[ VMIN ] = 1;
	tcsetattr( 0, TCSANOW, &ttystate );
}

void set_nodelay_mode()
{
	int	termflags;
	termflags = fcntl( 0, F_GETFL );
	termflags |= O_NDELAY;
	fcntl( 0, F_SETFL, termflags );
}

tty_mode( int how )
{
	static struct termios original_mode;
	static int original_flags;
	if ( how == 0 ){
		tcgetattr( 0, &original_mode );
		original_flags = fcntl( 0, F_GETFL );
	}
	else{
		tcsetattr( 0, TCSANOW, &original_mode );
		fcntl( 0,  F_SETFL, original_flags );
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值