函数名: ioctl 头文件:#include<sys/ioctl.h> 功 能: 控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。 用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]); 返回值:成功为0,出错为-1 usr/include/asm-generic/ioctl.h中定义的宏的注释: #define _IOC_NRBITS 8 //序数(number)字段的字位宽度,8bits #define _IOC_TYPEBITS 8 //幻数(type)字段的字位宽度,8bits #define _IOC_SIZEBITS 14 //大小(size)字段的字位宽度,14bits #define _IOC_DIRBITS 2 //方向(direction)字段的字位宽度,2bits #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) //序数字段的掩码,0x000000FF #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) //幻数字段的掩码,0x000000FF #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) //大小字段的掩码,0x00003FFF #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) //方向字段的掩码,0x00000003 #define _IOC_NRSHIFT 0 //序数字段在整个字段中的位移,0 #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) //幻数字段的位移,8 #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) //大小字段的位移,16 #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) //方向字段的位移,30 /* * Direction bits. */ #define _IOC_NONE 0U //没有数据传输 #define _IOC_WRITE 1U //向设备写入数据,驱动程序必须从用户空间读入数据 #define _IOC_READ 2U //从设备中读取数据,驱动程序必须向用户空间写入数据 #define _IOC(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) /* * used to create numbers */ //构造无参数的命令编号 #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) //构造从驱动程序中读取数据的命令编号 #define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) //用于向驱动程序写入数据命令 #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) //用于双向传输 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) /* *used to decode ioctl numbers.. */ //从命令参数中解析出数据方向,即写进还是读出 #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) //从命令参数中解析出幻数type #define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) //从命令参数中解析出序数number #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) //从命令参数中解析出用户数据大小 #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) /* ...and for the drivers/sound files... */ #define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) #define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) #define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) #define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) #define IOCSIZE_SHIFT (_IOC_SIZESHIFT) 程序例: #include <stdlib.h> #include <stdio.h> #include <sys/ioctl.h> int main(void) { ..int stat; /* use func 8 to determine if the default drive is removable */ ..stat = ioctl(0, 8, 0, 0); ..if (!stat) ....printf("Drive %c is removable.\n", getdisk() + 'A'); ..else ....printf("Drive %c is not removable.\n", getdisk() + 'A'); ..return 0; } int ioctl( int fd, int request, .../* void *arg */ ) 详解 第三个参数总是一个指针,但指针的类型依赖于request 参数。我们可以把和网络相关的请求划分为6 类: 套接口操作 文件操作 接口操作 ARP 高速缓存操作 路由表操作 流系统 下表列出了网络相关ioctl请求的request 参数以及arg 地址必须指向的数据类型:
套接口操作: 明确用于套接口操作的ioctl请求有三个, 它们都要求ioctl的第三个参数是指向某个整数的一个指针。 SIOCATMARK: 如果本套接口的的度指针当前位于带外标记,那就通过由第三个参数指向的整数返回一个非0 值;否则返回一个0 值。POSIX 以函数sockatmark 替换本请求。 SIOCGPGRP : 通过第三个参数指向的整数返回本套接口的进程ID 或进程组ID ,该ID 指定针对本套接口的SIGIO 或SIGURG 信号的接收进程。本请求和fcntl 的F_GETOWN 命令等效,POSIX 标准化的是fcntl 函数。 SIOCSPGRP : 把本套接口的进程ID 或者进程组ID 设置成第三个参数指向的整数,该ID 指定针对本套接口的SIGIO 或SIGURG 信号的接收进程,本请求和fcntl 的F_SETOWN 命令等效,POSIX 标准化的是fcntl 操作。
文件操作: 以下5 个请求都要求ioctl的第三个参数指向一个整数。 FIONBIO : 根据ioctl的第三个参数指向一个0 或非0 值分别清除或设置本套接口的非阻塞标志。本请求和O_NONBLOCK 文件状态标志等效,而该标志通过fcntl 的F_SETFL 命令清除或设置。 FIOASYNC : 根据iocl 的第三个参数指向一个0 值或非0 值分别清除或设置针对本套接口的信号驱动异步I/O 标志,它决定是否收取针对本套接口的异步I/O 信号(SIGIO )。本请求和O_ASYNC 文件状态标志等效,而该标志可以通过fcntl 的F_SETFL 命令清除或设置。 FIONREAD : 通过由ioctl的第三个参数指向的整数返回当前在本套接口接收缓冲区中的字节数。本特性同样适用于文件,管道和终端。 FIOSETOWN : 对于套接口和SIOCSPGRP 等效。 FIOGETOWN : 对于套接口和SIOCGPGRP 等效。
类别 | Request | 说明 | 数据类型 |
套 接 口 | SIOCATMARK SIOCSPGRP SIOCGPGRP | 是否位于带外标记 设置套接口的进程ID 或进程组ID 获取套接口的进程ID 或进程组ID | int int int |
文 件 | FIONBIO FIOASYNC FIONREAD FIOSETOWN FIOGETOWN | 设置/ 清除非阻塞I/O 标志 设置/ 清除信号驱动异步I/O 标志 获取接收缓存区中的字节数 设置文件的进程ID 或进程组ID 获取文件的进程ID 或进程组ID | int int int int int |
接 口 | SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFFLAGS SIOCGIFFLAGS SIOCSIFDSTADDR SIOCGIFDSTADDR SIOCGIFBRDADDR SIOCSIFBRDADDR SIOCGIFNETMASK SIOCSIFNETMASK SIOCGIFMETRIC SIOCSIFMETRIC SIOCGIFMTU SIOCxxx | 获取所有接口的清单 设置接口地址 获取接口地址 设置接口标志 获取接口标志 设置点到点地址 获取点到点地址 获取广播地址 设置广播地址 获取子网掩码 设置子网掩码 获取接口的测度 设置接口的测度 获取接口MTU (还有很多取决于系统的实现) | struct ifconf struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq |
ARP | SIOCSARP SIOCGARP SIOCDARP | 创建/ 修改ARP 表项 获取ARP 表项 删除ARP 表项 | struct arpreq struct arpreq struct arpreq |
路 由 | SIOCADDRT SIOCDELRT | 增加路径 删除路径 | struct rtentry struct rtentry |
流 | I_xxx |