在infi.storagemodel的infi.instruct包中定義了一套和C語言結(jié)構(gòu)體相互映射的機(jī)制秀又∶教瑁可以實(shí)現(xiàn)使用python調(diào)用linux系統(tǒng)調(diào)用帝簇,并且將調(diào)用結(jié)果封裝成結(jié)構(gòu)體徘郭。
以下是一個例子:
一、fcntl.ioctl
fcntl來自于fcntlmodule.so,是python中可以直接import的一個模塊丧肴,ioctl函數(shù)是一個系統(tǒng)調(diào)用函數(shù)残揉,原型是:
fcntl.ioctl(fd, op[, arg[, mutate_flag]])
- fd:文件句柄
- op:operation code,定義ioctl的執(zhí)行行為
- args:一個結(jié)構(gòu)體的指針,執(zhí)行結(jié)果將回寫到這個結(jié)構(gòu)體中去
執(zhí)行ioctl需要一個op_code,以及這個操作結(jié)果是一個什么樣的結(jié)構(gòu)體芋浮,op和結(jié)構(gòu)體的對應(yīng)關(guān)系需要發(fā)起系統(tǒng)調(diào)用的人提前知道抱环。
二、infi中定義一個結(jié)構(gòu)體
現(xiàn)在纸巷,我們使用op_code=2,去調(diào)用ioctl镇草,將會返回以下的結(jié)構(gòu)體:
#C語言中的定義
struct info{
char a;
int b;
};
在infi中使用python創(chuàng)建一個同樣的結(jié)構(gòu)體類,結(jié)構(gòu)體中兩個成員瘤旨,一個char梯啤,一個int:
#ioctl_structure.py
from infi.instruct import Struct
from infi.instruct import SNInt32,UBInt8
class Info(Struct):
_fields_=[
#unsigned char=UBInt8
UBInt8('ch'),
SNInt32('In'),
]
三、執(zhí)行ioctl
參見以下代碼:
#導(dǎo)入我們定義的結(jié)構(gòu)體
from ioctl_structure import Info
from array import array
from fcntl import ioctl as _ioctl
import os
#定義op
op_number=2
#size存哲,需要準(zhǔn)備幾個byte給ioctl因宇,由結(jié)構(gòu)體決定
size = Info.min_max_sizeof().max
print "size: ",size
buffer = array("B", [0]*size)
#獲取設(shè)備的文件句柄
fd = os.open('/dev/sdb', os.O_RDONLY | os.O_NONBLOCK)
args = [fd, op_number,]
args.extend([buffer, True])
print buffer
#執(zhí)行ioctl,結(jié)構(gòu)回寫在buffer中
result=_ioctl(*args)
print buffer
#通過buffer祟偷,生成我們的結(jié)構(gòu)體對象
result_struct=Info.create_from_string(buffer)
print result_struct.ch
print result_struct.In
>>>>>>>>>>>>>>>>>>>>>>>output>>>>>>>>>>>>>>>>>>>
size: 5
#原始buffer
array('B', [0, 0, 0, 0, 0])
#被回寫之后的buffer
array('B', [0, 16, 0, 0, 0])
#一個字節(jié)的的char察滑,和4個字節(jié)的int解析之后的結(jié)果(注意,是little-endian的字節(jié)序)
0
16