ioctl操作

概述

ioctl函数传统上一直作为那些不适合归入其他精细定义类别的特性的系统接口。例如,Unix终端接口传统上使用ioctl访问,然后POSIX为终端创造了12个新函数:tcgetattr:获取终端属性;tcflush:冲刷待处理输入或输出。

网络程序(特别是服务器程序)经常在程序启动执行后使用ioctl获取所在主机全部网络接口的信息,包括:接口地址、是否支持广播、是否支持多播等等。

 

  • ioctl函数

#include <unistd.h>

int ioctl(int fd, int request, ... /* void *arg */);

//返回:若成功则为0,若出错则为-1

其中第三个参数总是一个指针,但指针的类型依赖于request参数。

我们可以把和网络相关的请求(request)划分为6类:

  • 套接字套作
  • 文件操作
  • 接口操作
  • ARP高速缓存操作
  • 路由表操作
  • 流系统

以下是网络相关ioctl请求的request参数以及arg地址必须指向的数据类型:

  • 套接字操作

明确用于套接字的ioctl请求有3个。它们都要求ioctl的第三个参数是指向某个整数的一个指针。

  • SIOCATMARK:如果本套接字的读指针当前位于带外标记,那就通过由第三个参数指向的整数返回一个非0值;否则返回一  个0值;
  • SIOCGPGRP:通过由第三个参数指向的整数返回本套接字的进程ID或进程组ID,该ID指定针对本套接字的SIGIO或SIGURG信号的接收进程。本请求和fcntl的F_GETOWN命令等效;
  • SIOCSPGRP:把本套接字的进程ID或进程组ID设置成由第三个参数指向的整数,该ID指定针对本套接字的SIGIO或SIGURG信号的接收进程。本请求和fcntl的F_SETOWN命令等效;

 

  • 文件操作

以下5个请求都要求ioctl的第三个参数指向一个整数:

  • FIONBIO:根据ioctl的第三个参数指向一个0值或非0值,可清除或设置本套接字的非阻塞式I/O标志。本请求和O_NONBLOCK文件状态标志等效,而可以通过fcntl的F_SETFL命令清除或设置该标志;
  • FIOASYNC:根据ioctl的第三个参数指向一个0值或非0值,可清除或设置针对本套接字的信号驱动异步I/O标志,它决定是否收取针对本套接字的异步I/O信号(SIGIO)。本请求和O_ASYNC文件状态标志等效,而可以通过fcntl的F_SETFL命令清除或设置该标志;
  • FIONREAD:通过由ioctl的第三个参数指向的整数返回当前在本套接字接收缓冲区中的字节数;
  • FIOSETOWN:对于套接字和SIOCSPGRP等效;
  • FIOGETOWN:对于套接字和SIOCGPFRP等效;

 

  • ARP高速缓存操作

ARP高速缓存也通过ioctl函数曹忠。这些请求使用arpreq结构,它定义在头文件<net/if_arp.h>中:

strcut arpreq{
    struct sockaddr arp_pa;
    struct sockaddr arp_ha;
    int             arp_flags;
};

#define ATF_INUSE    0x01
#define ATF_COM      0X02
#define ATF_PERM     0x04
#define ATF_PUBL     0x08

ioctl的第三个参数必须指向某个arpreq结构。操纵ARP高速缓存的ioctl请求有3个:

  • SIOCSARP:把一个新的表项加到ARP高速缓存,或者修改其中已经存在的一个表项。其中arp_pa是一个含有IP地址的网际网套接字地址结构,arp_ha则是一个通用套接字地址结构,它的sa_family值为AF_UNSPEC,sa_data中含有硬件地址。ATF_PERM和ATF_PUBL这两个标志也可以由应用程序制定。另两个则由内核设置;
  • SIOCDARP:从ARP高速缓存中删除一个表项。调用者指定要删除表项的网际网地址;
  • SIOCGARP:从ARP高速缓存中获取一个表项。调用者指定网际网地址,相应的硬件地址(例如以太网地址)随标志一起返回;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
F81866A 是一种 Super I/O 芯片,它主要用于电脑主板上的各种接口控制,包括 GPIO。在 Linux 中,我们可以使用 ioctl 系统调用来控制 F81866A 芯片上的 GPIO。具体来说,我们可以通过访问 /dev/io 对应的设备文件来进行 ioctl 操作。 下面是一个简单的示例代码,演示如何使用 ioctl 操作 F81866A 芯片上的 GPIO: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #define F81866A_GPIO_BASE 0x4E #define F81866A_IOCTL_SET_PIN_MODE _IOW(F81866A_GPIO_BASE, 1, int) #define F81866A_IOCTL_SET_PIN_VALUE _IOW(F81866A_GPIO_BASE, 2, int) #define F81866A_PIN_MODE_INPUT 0 #define F81866A_PIN_MODE_OUTPUT 1 #define F81866A_PIN_VALUE_LOW 0 #define F81866A_PIN_VALUE_HIGH 1 int main(int argc, char **argv) { int fd = open("/dev/io", O_RDWR); if (fd < 0) { perror("open"); exit(1); } int pin_number = 1; // GPIO1 int pin_mode = F81866A_PIN_MODE_OUTPUT; int pin_value = F81866A_PIN_VALUE_HIGH; // 设置 GPIO1 为输出模式 if (ioctl(fd, F81866A_IOCTL_SET_PIN_MODE, pin_number | (pin_mode << 8)) < 0) { perror("ioctl F81866A_IOCTL_SET_PIN_MODE"); exit(1); } // 设置 GPIO1 输出高电平 if (ioctl(fd, F81866A_IOCTL_SET_PIN_VALUE, pin_number | (pin_value << 8)) < 0) { perror("ioctl F81866A_IOCTL_SET_PIN_VALUE"); exit(1); } close(fd); return 0; } ``` 在上面的示例代码中,我们首先打开设备文件 /dev/io,然后使用 ioctl 系统调用向 F81866A 芯片发送命令,以控制 GPIO1 的输出模式和输出电平。具体的命令码和参数定义可以参考 F81866A 的数据手册。需要注意的是,由于 F81866A 芯片是一种 I/O 设备,因此我们需要以 root 用户身份运行程序才能够操作该设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值