美文网首页
infi.storagemodel中,发起ioctl命令并解析结

infi.storagemodel中,发起ioctl命令并解析结

作者: Stansosleepy | 来源:发表于2015-08-06 15:51 被阅读121次

    在infi.storagemodel的infi.instruct包中定义了一套和C语言结构体相互映射的机制。可以实现使用python调用linux系统调用,并且将调用结果封装成结构体。
    以下是一个例子:

    一、fcntl.ioctl
    fcntl来自于fcntlmodule.so,是python中可以直接import的一个模块,ioctl函数是一个系统调用函数,原型是:

    fcntl.ioctl(fd, op[, arg[, mutate_flag]])

    • fd:文件句柄
    • op:operation code,定义ioctl的执行行为
    • args:一个结构体的指针,执行结果将回写到这个结构体中去

    执行ioctl需要一个op_code,以及这个操作结果是一个什么样的结构体,op和结构体的对应关系需要发起系统调用的人提前知道。

    二、infi中定义一个结构体

    现在,我们使用op_code=2,去调用ioctl,将会返回以下的结构体:

    #C语言中的定义
    struct info{
    char a;
    int b;
    };
    

    在infi中使用python创建一个同样的结构体类,结构体中两个成员,一个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'),
                 ]
    

    三、执行ioctl

    参见以下代码:

    #导入我们定义的结构体
    from ioctl_structure import Info
    from array import array
    from fcntl import ioctl as _ioctl
    import os
    #定义op
    op_number=2
    
    #size,需要准备几个byte给ioctl,由结构体决定
    size = Info.min_max_sizeof().max
    print "size: ",size
    buffer = array("B", [0]*size)
    #获取设备的文件句柄
    fd = os.open('/dev/sdb', os.O_RDONLY | os.O_NONBLOCK)
    args = [fd, op_number,]
    args.extend([buffer, True])
    print buffer
    #执行ioctl,结构回写在buffer中
    result=_ioctl(*args)
    print buffer
    #通过buffer,生成我们的结构体对象
    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])
    #一个字节的的char,和4个字节的int解析之后的结果(注意,是little-endian的字节序)
    0
    16

    相关文章

      网友评论

          本文标题:infi.storagemodel中,发起ioctl命令并解析结

          本文链接:https://www.haomeiwen.com/subject/hbcbqttx.html