為了便於通過程式來獲得和修改終端參數,Linux還提供了tcgetattr函數和tcsetattr函數。tcgetattr用於擷取終端的相關參數,而tcsetattr函數用於設定終端參數。這兩個函數的具體資訊如表6.2所示。
表6.2 tcgetattr函數和tcsetattr函數
|
標頭檔 |
<termios.h>
<unistd.h> |
|
函數形式 |
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p); |
|
傳回值 |
成功 |
失敗 |
是否設定errno |
|
0 |
−1 |
是 |
說明:tcgetattr函數用於擷取與終端相關的參數。參數fd為終端的檔案描述符,返回的結果儲存在termios結構體中,該結構體一般包括如下的成員:
tcflag_t c_iflag;
tcflag_t c_oflag;
tcflag_t c_cflag;
tcflag_t c_lflag;
cc_t c_cc[NCCS];
其具體意義如下:
c_iflag:輸入模式標誌,控制終端輸入方式,具體參數如表6.3所示。
表6.3 c_iflag參數表
|
鍵 值 |
說 明 |
|
IGNBRK |
忽略BREAK鍵輸入 |
|
BRKINT |
如果設定了IGNBRK,BREAK鍵的輸入將被忽略,如果設定了BRKINT ,將產生SIGINT中斷 |
|
IGNPAR |
忽略同位錯誤 |
|
PARMRK |
標識同位錯誤 |
|
INPCK |
允許輸入同位 |
|
ISTRIP |
去除字元的第8個位元 |
|
INLCR |
將輸入的NL(換行)轉換成CR(斷行符號) |
|
IGNCR |
忽略輸入的斷行符號 |
|
ICRNL |
將輸入的斷行符號轉化成換行(如果IGNCR未設定的情況下) |
|
IUCLC |
將輸入的大寫字元轉換成小寫字元(非POSIX) |
|
IXON |
允許輸入時對XON/XOFF流進行控制 |
|
IXANY |
輸入任何字元將重啟停止的輸出 |
|
IXOFF |
允許輸入時對XON/XOFF流進行控制 |
|
IMAXBEL |
當輸入隊列滿的時候開始響鈴,Linux在使用該參數而是認為該參數總是已經設定 |
c_oflag:輸出模式標誌,控制終端輸出方式,具體參數如表6.4所示。
表6.4 c_oflag參數
|
鍵 值 |
說 明 |
|
OPOST |
處理後輸出 |
|
OLCUC |
將輸入的小寫字元轉換成大寫字元(非POSIX) |
|
ONLCR |
將輸入的NL(換行)轉換成CR(斷行符號)及NL(換行) |
|
OCRNL |
將輸入的CR(斷行符號)轉換成NL(換行) |
|
ONOCR |
第一行不輸出斷行符號符 |
|
ONLRET |
不輸出斷行符號符 |
|
OFILL |
發送填充字元以延遲終端輸出 |
|
OFDEL |
以ASCII碼的DEL作為填充字元,如果未設定該參數,填充字元將是NUL(‘/0’)(非POSIX) |
|
NLDLY |
換行輸出延時,可以取NL0(不延遲)或NL1(延遲0.1s) |
|
CRDLY |
斷行符號延遲,取值範圍為:CR0、CR1、CR2和 CR3 |
|
TABDLY |
水平定位字元輸出延遲,取值範圍為:TAB0、TAB1、TAB2和TAB3 |
|
BSDLY |
空格輸出延遲,可以取BS0或BS1 |
|
VTDLY |
垂直定位字元輸出延遲,可以取VT0或VT1 |
|
FFDLY |
換頁延遲,可以取FF0或FF1 |
c_cflag:控制模式標誌,指定終端硬體控制資訊,具體參數如表6.5所示。
表6.5 c_oflag參數
|
鍵 值 |
說 明 |
|
CBAUD |
傳輸速率(4+1位)(非POSIX) |
|
CBAUDEX |
附加傳輸速率(1位)(非POSIX) |
|
CSIZE |
字元長度,取值範圍為CS5、CS6、CS7或CS8 |
|
CSTOPB |
設定兩個停止位 |
|
CREAD |
使用接收器 |
|
PARENB |
使用同位 |
|
PARODD |
對輸入使用同位,對輸出使用偶校正 |
|
HUPCL |
關閉裝置時掛起 |
|
CLOCAL |
忽略數據機線路狀態 |
|
CRTSCTS |
使用RTS/CTS流量控制 |
c_lflag:本地模式標誌,控制終端編輯功能,具體參數如表6.6所示。
表6.6 c_lflag參數
|
鍵 值 |
說 明 |
|
ISIG |
當輸入INTR、QUIT、SUSP或DSUSP時,產生相應的訊號 |
|
ICANON |
使用標準輸入模式 |
|
XCASE |
在ICANON和XCASE同時設定的情況下,終端只使用大寫。如果只設定了XCASE,則輸入字元將被轉換為小寫字元,除非字元使用了逸出字元(非POSIX,且Linux不支援該參數) |
|
ECHO |
顯示輸入字元 |
|
ECHOE |
如果ICANON同時設定,ERASE將刪除輸入的字元,WERASE將刪除輸入的單詞 |
|
ECHOK |
如果ICANON同時設定,KILL將刪除當前行 |
|
ECHONL |
如果ICANON同時設定,即使ECHO沒有設定依然顯示分行符號 |
|
ECHOPRT |
如果ECHO和ICANON同時設定,將刪除列印出的字元(非POSIX) |
|
TOSTOP |
向後台輸出發送SIGTTOU訊號 |
c_cc[NCCS]:控制字元,用於儲存終端驅動程式中的特殊字元,如輸入結束符等。c_cc中定義了如表6.7所示的控制字元。
表6.7 c_cc支援的控制字元
|
宏 |
說 明 |
宏 |
說 明 |
|
VINTR |
Interrupt字元 |
VEOL |
附加的End-of-file字元 |
|
VQUIT |
Quit字元 |
VTIME |
非規範模式讀取時的逾時時間 |
|
VERASE |
Erase字元 |
VSTOP |
Stop字元 |
|
VKILL |
Kill字元 |
VSTART |
Start字元 |
|
VEOF |
End-of-file字元 |
VSUSP |
Suspend字元 |
|
VMIN |
非規範模式讀取時的最小字元數 |
|
|
tcsetattr函數用於設定終端的相關參數。參數fd為開啟的終端檔案描述符,參數optional_actions用於控制修改起作用的時間,而結構體termios_p中儲存了要修改的參數。
optional_actions可以取如下的值。
TCSANOW:不等資料轉送完畢就立即改變屬性。
TCSADRAIN:等待所有資料轉送結束才改變屬性。
TCSAFLUSH:清空輸入輸出緩衝區才改變屬性。
錯誤資訊:
EBADF:非法的檔案描述符。
EINTR:tcsetattr函數調用被訊號中斷。
EINVAL:參數optional_actions使用了非法值,或參數termios中使用了非法值。
ENCTTY:非終端的檔案描述符。
執行個體演練:
程式p6.2.c通過修改終端控制字元,將終端輸入結束符由“Ctrl+D”,修改成了“Ctrl+G”。首先,程式調用tcgetattr函數獲得標準輸入的termios資訊,將termios結構體中的c_cc[VEOF]控制字元的修改成0x07(即Ctrl+G);然後,使用tcsetattr函數將修改後的termios參數設定到終端中。具體代碼如下所示:
//p6.2.c 修改終端控制字元樣本#include <stdio.h>#include <termios.h>#include <unistd.h>#include <errno.h> int main(void){//term用於儲存獲得的終端參數資訊struct termios term;int err; //獲得標準輸入的終端參數,將獲得的資訊儲存在term變數中if(tcgetattr(STDIN_FILENO,&term)==-1){perror("Cannot get standard input description");return 1;} //修改獲得的終端資訊的結束控制字元term.c_cc[VEOF]=(cc_t)0x07; //使用tcsetattr函數將修改後的終端參數設定到標準輸入中//err用於儲存函數調用後的結果err=tcsetattr(STDIN_FILENO,TCSAFLUSH,&term); //如果err為-1或是出現EINTR錯誤(函數執行被訊號中斷),//給出相關出錯資訊if(err==-1 && err==EINTR){perror("Failed to change EOF character");return 1;} return 0;}
|
使用gcc編譯p6.2.c程式,得到名為p6.2的可執行程式。在執行p6.2程式前,按“Ctrl+D”可以使終端結束。執行p6.2程式後,按“Ctrl+D”失去了作用,而輸入“Ctrl+G”實現了原來“Ctrl+D”的功能。
原文地址:http://blog.csdn.net/xuefu2008/article/details/4662368