2009-09-18 32 views
3

为了避免依赖无线工具,我想直接从ioctl的设备上获取essid,在C中这不会是一个问题,但在Ruby中它是完全不同的。在ruby中通过ioctl获取essid

问题是从以下结构wireless.h被用作IOCTL的输入/答复:

struct iw_point 
{ 
    void __user *pointer; /* Pointer to the data (in user space) */ 
    __u16 length; /* number of fields or size in bytes */ 
    __u16 flags; /* Optional params */ 
}; 

指针部分必须是一个存储区域的有效地址,随后在长度字节,后面跟着一个标志字段。我尝试使用Array#pack和bit-struct gem,但尚未找到解决方案。

有没有办法绕过这个内存指针的问题?

回答

4

我终于得到它的工作,解决方案是使用包用这种方式“P”的说法:

require "socket" 

# Copied from wireless.h 
SIOCGIWESSID  = 0x8B1B 
IW_ESSID_MAX_SIZE = 32 

iwreq = [ "wlan0", " " * IW_ESSID_MAX_SIZE, IW_ESSID_MAX_SIZE, 0 ].pack("a16pII") 

sock = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0) 

sock.ioctl(SIOCGIWESSID, iwreq) 

interface, essid, len, flags = iwreq.unpack("a16pII") 

puts essid 
1

当然,只需将您自己的Ruby友好界面定义为围绕ioctl的包装(C语言)即可。我确实在Ruby中看到了默认的ioctl问题。我猜ios.ioctl主要是用于ioctl“写”的电话。

+0

好了,想我没有别的选择。实际上,ioctl应该能够正确地工作,而不仅仅是在使用像上面这样的结构时发生段错误。 ;) – unexist 2009-09-19 17:44:59

+0

我最近还没有看过ioctl的胆量,但是如果loonix版本与非BSD unix类似,它有一个可怕的含糊之处,因为知道它是读还是写,还是需要知道多少ioctl和设备。 (!) – DigitalRoss 2009-09-19 18:41:06

+0

确实如此,但设备通常必须遵循客户可使用的草稿,最适合供应商和/或驱动程序作者使用。这种情况下的问题就是Ruby中缺少指针,可能无法通过构造来轻松覆盖。 在我的窗口管理器工作期间,我意识到Ruby的C API - 所以这完全没有问题。 :) – unexist 2009-09-21 07:58:26