1. 程式人生 > >unix/linux程式設計實踐教程:學習stty

unix/linux程式設計實踐教程:學習stty

1. 終端實際上就是一個檔案:

[email protected]:~$ tty
/dev/pts/0
[email protected]:~$ who > /dev/pts/0
leichaojian :0           2014-08-28 19:54 (:0)
leichaojian pts/0        2014-08-28 20:17 (:0)
[email protected]:~$ 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 );
        }
}
    正常程式執行如下:
[email protected]:~$ vim rotate.c
[email protected]:~$ cc rotate.c
[email protected]:~$ ./a.out
ab<-cd
bc<-de
efg^C

    但是,我們使用stty -icanon關閉了驅動程式中的規範模式處理,這時候並沒有緩衝,所以輸入後馬上會顯示結果:
[email protected]:~$ stty -icanon; ./a.out
abbcxycdde

effggh^C
[email protected]
:~$ stty icanon [email protected]:~$ ./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 );
	}
}


相關推薦

unix/linux程式設計實踐教程學習stty

1. 終端實際上就是一個檔案: [email protected]:~$ tty /dev/pts/0 [email protected]:~$ who > /dev/pts/0 leichaojian :0 2014-08-

unix/linux程式設計實踐教程who命令

1. who命令的編寫 1) 通過man命令的幫助,找到who命令的儲存檔案 man who2) 在man who的幫助下,找到utmp這個資訊 man -k utmp 3) 看man -k utmp的輸出,找到以下這條資訊: utmp (5)

學習Unix/Linux程式設計實踐教程》(2)實現 more

0.目錄 1.more 能做什麼? 2.more 是如何實現的? 3.實現 more 3.1 more01.c 3.2 more02.c 3.3 more03.c 1.more 能做什麼? more 可以分頁顯示檔案的內容。正常執行後 more 會顯示檔案第一屏的內容,在螢幕的底

Unix-Linux 程式設計實踐教程 第十章 小結

檔案描述符是一個資源陣列的索引,每次取最小的用,0、1、2分別代表stdin,stdout,stderr三個標準IO的描述符。重定向只需close其中其中一個,然後再開啟一個檔案描述符,系統自動將關閉掉的索引重新使用。比如close(0),open(x-file,"r"),此時就是將stdi

Unix-Linux 程式設計實踐教程 第八章 小結

執行程式的函式---execvp()                     &n

Unix-Linux 程式設計實踐教程 第七章 小結

設定傳送訊號的計時器---alarm()alarm()設定當前程序的計時器到seconds秒後收到由核心發來的SIGALARM訊號 pause()掛起呼叫程序知道一個訊號到達,如果呼叫程序被整個訊號終止,pause()則不會返回。 三種計時器: ITIMER_

Unix-Linux 程式設計實踐教程 第五章 小結

裝置檔案中用逗號連線起來的兩個數字為主裝置號和從裝置號。主裝置號確定實際的裝置驅動程式,從裝置號作為引數。 如下圖中的,主裝置號-4,從裝置號-2 裝置檔案中的i-node儲存的是指向核心子程式指標 fcntl()針對當前fd描述的連線,執行操作,並不會改變檔案本身的屬性。

Unix-Linux 程式設計實踐教程 第四章 小結

建立目錄的函式---mkdir(const char *pathname, mode_t mode); #include <sys/stat.h> #include <sys/types.h> //pathname中可接受,“/home/tmp”和“/home/t

Unix-Linux 程式設計實踐教程 第三章 小結

Linux下一切皆檔案,所以目錄也只是一種特殊的檔案,可以同文件一樣open,read,close,只是函式換成了opendir(),readdir(),closedir() 用於讀取目錄檔案的資料結構---struct dirent #include <dirent.h>

Unix-Linux 程式設計實踐教程 第二章 小結

utmp檔案記錄當前正在本系統中的使用者的登入資訊 wtmp檔案記錄登入過本系統的使用者的登入資訊     PS:man who命令即可查詢到utmp和wtmp檔案在當前系統的位置 who命令相關: who顯示當前已登入使用

unix/linux程式設計實踐教程C語言補充(2)

1 getchar()和putchar()函式 getchar()函式的功能是從終端接受一個字元。可以將其置於程式中實現暫停功能。 getchar()函式接受的字元可以賦給一個字元型或整型變數,也可以賦給任何變數,直接輸出。 putchar(引數)  引數可以是一個字元

Unix/Linux程式設計實踐教程–ac在Ubuntu 14.04的實現

環境:Ubuntu 14.04 32位 為什麼這回不寫在OS x上的實現了?因為OS X使用的是utmpx,然後我用getutxent_wtmp()這個函式也沒有辦法正確獲取wtmp的日誌資訊,所以先在Ubuntu上實現好了。 預設沒有帶ac這個程式,需要自

Unix/Linux程式設計實踐教程–od在OS X的實現

環境:OS X 10.12.4 抱歉,本文章並不是關於Ollydbg的實現(笑)。 照舊man 1 od。 od 是一個能把指定的檔案或者標準輸入按照使用者定義的格式列印。( The od utility is a filter which displa

Unix/Linux程式設計實踐教程–chmod在Centos7.3的實現

環境:centos 7.3 x86_64 如果搜一下man就會發現,裡面有兩個chmod,一個是chmod(1),一個是chmod(2)。根據牛頓-萊布尼茲公式,立即推,第一個是使用者命令,第二個是系統呼叫。系統呼叫裡,函式的原型是這樣的: int chmo

Unix/Linux程式設計實踐教程–書評

花了兩個月的時間把這本書讀完了,完成了一部分的課後習題。 總的來說,這是一本挺好的Unix\Linux程式設計的入門書(雖然書中的小錯誤一大堆),書的開始部分簡要介紹了Unix系統程式設計,講述瞭如何使用男人(man page),這也是我比較看好的,授人以漁,

Unix/Linux程式設計實踐教程–cat在OS X的實現

環境:OS X 10.12.4 cat 這玩意兒在哪個Unix平臺實現都一樣吧- - cat這個程式是把引數中的檔名的檔案內容輸出到標準輸出,如果引數中沒有檔名,預設是把標準輸入的內容輸出到標準輸出。 這裡使用了utmplib類似的程式碼用於快取資料,減少

Unix/Linux程式設計實踐教程(一)

-------------------------------前言呃。。。。開始入坑linux。參考書當然是《Unix/Linux程式設計實踐教程》現寫下心得筆記,有什麼不對的,請大家指正哈。------------------------------修正2018.5.13貌

Unix-Linux程式設計實踐教程》讀書筆記(一)

寫在最前:          第一遍:零零散散的花了近兩個月的時間讀了本書的第一遍,這是一本很適合剛剛掌握一些計算機基礎知識的人讀的書。學習的思路非常明確,能做什麼?怎麼做?自己動手?三個方面符合認知順序,由淺入深讓人易於接受;而且每章的內容相對獨立和簡單,適合初次接觸類

Unix/Linux程式設計實踐】檔案系統編寫pwd

知識點 目錄是一個包含檔名與i-節點對的列表的檔案。 ”檔案在目錄中“的含義:目錄中存放的只是檔案在i-節點表的入口,而檔案的內容則儲存在資料區中。例如,“檔案x在目錄a中”意味著在目錄a中有一個指向檔案x的i-節點的連結,這個連結所附加的檔名為x。 pw

Unix-Linx 程式設計實踐教程 第六章 小結

終端模式有三種,規範模式、非規範模式、raw模式。 規範模式:又名cooked模式,是最常見的模式。擁有緩衝區特性(僅在接收到回車鍵時才將輸入傳送到程式),使得驅動程式可以實現基本的編輯功能。可通過命令stty或tcsetattr()修改。 非規範模式:沒有緩衝