by francis_hao aug 27,2017
unpv1對ioctl有算是比較詳細的介紹,但是,這些request和後面的資料型別是從**來的,以及引數具體該如何使用呢?本文嘗試在不借助書籍,而僅僅使用linux系統下的資源編寫可行的呼叫ioctl的程式。
ioctl – 控制裝置
#include
intioctl(intd,intrequest,...);
ioctl()函式操縱由引數指定的裝置檔案,引數d必須是乙個開啟的檔案描述符。第二個引數是乙個依賴於裝置的請求碼。第三個引數是乙個指向記憶體的無型別指標,在void *沒有出來之前,此項為char *argp,在之後的討論中,我們會使用這個名字。
比較重要的第二個引數,它指明了引數是輸入引數還是輸出引數,還有引數argp的大小。有關request的巨集和其他定義在檔案中。通過ioctl_list(2)也可以看到這些呼叫列表。
在ioctl_list(2)中,每個ioctl呼叫的請求碼數值、名字和它需要的引數型別都給出了。其中,類似const struct foo *的型別表示是向核心傳入的引數,類似struct foo *的型別是從核心傳出的引數,如果核心既使用引數傳入,也使用引數傳出,那麼將會用// i-o標識。有些ioctl()函式可能會需要更多的引數,或者返回更多的引數而不僅僅是乙個結構體,那麼將會用// more標識。
乙個可能的列表
其中,第一行表示下面的常量所在的標頭檔案,下面的三列分別表示請求碼數值、常量名和它需要的引數型別。
然後在相應的標頭檔案中,大部分都會有該常量作用的描述。
通常,成功會返回0,但也有些請求碼將返回值作為結果,非負值為成功。如果出錯返回-1,並且errno被置為相應的值。
比如現在有乙個簡單的需求,獲取網絡卡的ip位址。首先在ioctl_list(2)裡搜尋addr,根據搜尋的結果檢視所屬的標頭檔案,得到如下資訊
得到get pa address的siocgifaddr和需要的引數struct ifreq *,並且該引數是i-o形式,通過man –k查詢struct ifreq的定義:
structifreq;
};
因為這個結構體比較簡單,能夠看出來輸入和輸出引數分別是哪個字段,有些結構體並不能很明顯的看出這些,就需要查閱其他資料了。可以通過man –k 查詢請求名,結合起來看會得到需要輸入什麼,輸出什麼。例如siocgifname:
根據以上內容便可以程式設計了,示例**如下
#include
#include
#include
#include
#include
#include
intmain(void)
strcpy(hw.ifr_name,"eno16777728");
ret=ioctl(fd,siocgifaddr,&hw);
if(ret<0)
pa=(structsockaddr_in*)&hw.ifr_addr;
printf("ip is %s\n",inet_ntoa(pa->sin_addr));
return0;
}
執行結果
man 2 ioctl
man 2 ioctl_list
man man
w.richard stevens著,楊繼張譯,unix網路程式設計卷1(第三版) 北京:人民郵電出版社,2023年6月
ioctl函式介紹
我這裡說的ioctl函式是在驅動程式裡的,因為我不知道還有沒有別的場合用到了ioctl,所以就規定了我們討論的範圍。為什麼要寫篇文章呢,是因為我前一陣子被ioctl給搞混 了,這幾天才弄明白它,於是在這裡清理一下頭腦。一 什麼是ioctl。ioctl是裝置驅動程式中對裝置的i o通道進行管理的函式。...
ioctl 函式詳解
int ioctl struct inode struct file unsigned int,unsigned long 這是驅動程式裝置控制介面函式 ioctl函式 的核心原型定義,struct inode 和 struct file 描述了操作的檔案,unsigned int 描述了ioctl...
Linux系統中ioctl 用法
一 什麼是ioctl。ioctl是裝置驅動程式中對裝置的i o通道進行管理的函式。所謂對i o通道進行管理,就 是對裝置的一些特性進行控制,例如串列埠的傳輸波特率 馬達的轉速等等。它的呼叫個數 如下 int ioctl int fd,ind cmd,其中fd就是使用者程式開啟裝置時使用open函式返...