終端連接控制(stty的編寫)

一、背景

文件與目錄在之前已經學習過了。文件中包含著數據,這些數據可以被讀出、寫入,也可以用以操作。但文件不僅僅是計算機唯一的數據來源,計算機的數據還可以來自於許多的外部設備,比如掃描儀、照相機、鼠標等輸入設備,還有揚聲器、打印機等輸出設備。總之數據來源多種多樣,並不僅侷限於文件。那麼這些外部設備的連接是怎麼樣的呢,其與進程協同工作時的方式(屬性)如何來修改呢。這就是本文所要探究的。

二、外部設備與磁盤文件的聯繫

文件我們都已經很熟悉了,文件通過目錄中的文件名來定位,文件名有一個i-節點與之對應。而i-節點中有文件的屬性且包含著指針列表(此指針列表指向文件的數據內容)。而實際上,外部設備在unix系統中也是以文件的形式存儲的。我們可以從文件中讀數據也可以寫數據。同樣,我們也可以向設備文件寫數據或從中讀出數據。

外部設備的文件一般存儲於/dev中。

終端連接控制(stty的編寫)

這裡顯示的是我的一些設備文件。但是並不是說所有的設備文件必須要存儲於/dev下,並不是這樣的,只是一種約定成俗的習慣,當然也可以在別的目錄下創建設備文件。

三、終端文件

要想看自己的終端文件名,只需輸入tty即可。我的(root)終端文件是這樣的。

終端連接控制(stty的編寫)

而在另一個終端的用戶的終端文件是這樣的。

終端連接控制(stty的編寫)

如此,如我前面所述,如果我可以使用root用戶往/dev/pts/1文件中寫入數據,那麼應該就可以在用戶pf的屏幕上顯示出我所寫入的數據。這樣,我寫了一段代碼用於此功能,實際上這個即是命令write的功能。

如下所示:

終端連接控制(stty的編寫)

終端連接控制(stty的編寫)

這就很清楚的演示了設備文件(終端文件)的操作方法與磁盤文件十分類似,許多的系統調用也都是通用的。

四、外部設備與磁盤文件的不同

第二節講了它們是十分相似的,都是以文件形式來進行操作。並且系統調用往往也是通用的。但它們卻不可能是完全相同的。不同之處主要體現在連接屬性上。對於文件來說,它們與進程進行數據的傳輸是需要緩衝的,緩衝用於文件數據的傳輸上好處很多,最突出的是緩衝可以容錯,而且緩衝是以塊為單位傳輸的,比起字節為單位傳輸,效率要高很多。但這是文件的連接屬性之一,可以開啟也可以關閉。但對於終端來說(以終端為例),當然是不需要緩衝,數據需要儘快的從進程傳輸到終端上來。並且終端也有其許多的連接屬性是文件連接屬性所沒有的,比如回顯、奇偶位、暫停位。

五、終端連接的屬性

文件連接的屬性這裡就不囉嗦了,我主要想討論一下終端連接的屬性。

命令stty用於顯示或修改終端的連接屬性。

顯示全部的終端連接屬性用-a參數。如下所示:

終端連接控制(stty的編寫)

這裡有三種類型的屬性,一種是開關型,一種是數字型、一種是字符控制型。類型是這麼分的,在修改對應類型的屬性時也是不同的。具體如何修改?對於開關型的屬性,只需輸入stty (-)屬性名,括號中的減號可加可不加,若不加,則是打開此屬性開關,若加,則是關閉此屬性開關。對於數字型與字符控制型,只需輸入stty 屬性名 修改值,當然,需要修改什麼屬性就輸入什麼屬性名,而修改值根據自己的需求來定。

六、stty的編程

stty的編程並不複雜,主要會使用兩個系統調用:tcgetattr、tcsetattr。前一個用來將設備文件的信息傳出來,後一個用來將修改過後的信息傳回去。並使用掩碼來進行測試、置位與清除位。

這裡我先編寫了一個簡單的echo的開關文件。結果如下所示:

終端連接控制(stty的編寫)

代碼如下:

#include

#include

#include

int main()

{

struct termios info;

if(tcgetattr(0,&info)==-1){

perror("tcgetattr");

exit(1);

}

else{

if(info.c_lflag&ECHO)

info.c_lflag&=~ECHO;

else

info.c_lflag|=ECHO;

if(tcsetattr(0,TCSANOW,&info)==-1)

perror("tcsetattr");

}

}

自己編寫的stty結果如下:

終端連接控制(stty的編寫)

我這裡還是拿echo來做測試的,因為結果很明顯。


分享到:


相關文章: