如何使用nix的ioctl?

Jod*_*omi 8 linux rust

我想打电话ioctl给Rust.我知道我应该使用nix箱子,但究竟是怎么回事?从文档中不清楚.

我有这个C:

int tun_open(char *devname)
{
  struct ifreq ifr;
  int fd, err;

  if ( (fd = open("/dev/net/tun", O_RDWR)) == -1 ) {
       perror("open /dev/net/tun");exit(1);
  }
  memset(&ifr, 0, sizeof(ifr));
  ifr.ifr_flags = IFF_TUN;
  strncpy(ifr.ifr_name, devname, IFNAMSIZ);  

  /* ioctl will use if_name as the name of TUN 
   * interface to open: "tun0", etc. */
  if ( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) == -1 ) {
    perror("ioctl TUNSETIFF");close(fd);exit(1);
  }
  //..........
Run Code Online (Sandbox Code Playgroud)

如何使用nix箱子做同样的事情?TUN*nix crate 中没有常量,并且不清楚如何使用ioctl宏.

wim*_*ica 9

rust-spidev中有一些示例用法.我将尝试将其应用于您的代码.

TUNSETIFF定义为:

#define TUNSETIFF     _IOW('T', 202, int)
Run Code Online (Sandbox Code Playgroud)

这将是使用nix的Rust:

const TUN_IOC_MAGIC: u8 = 'T' as u8;
const TUN_IOC_SET_IFF: u8 = 202;
ioctl!(write tun_set_iff with TUN_IOC_MAGIC, TUN_IOC_SET_IFF; u32);
Run Code Online (Sandbox Code Playgroud)

上面的宏将定义函数,你可以这样调用:

let err = unsafe { tun_set_iff(fd, ifr) }; // assuming ifr is an u32
Run Code Online (Sandbox Code Playgroud)

  • @Jodooomi这里的rust-spidev仅用于演示如何正确使用nix的`ioctl!`宏.由于`ioctl`是开放式的并且本质上不安全,因此不可能提供适用于所有情况的单一定义.相反,`nix`提供`ioctl!`宏作为*helper*来定义为`ioctl`的特定用途提供安全(或至少方便)接口的函数. (3认同)
  • @Cecile看起来`ioctl!`被分成了几个函数,例如`ioctl_read!`,`ioctl_write_ptr!`,`ioctl_write_buf!`等等:https://github.com/nix-rust/nix/blob/ master/src/sys/ioctl/mod.rs。因此,根据 ioctl 的用法,您将需要不同的名称。看起来这个例子是“ioctl_write_int!”。但最好阅读 mod.rs 中的文档,它比我解释得更好。 (2认同)