• Linux系统编程(4)——文件与IO之ioctl函数


    ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的参数个数如下:int ioctl(int fd, int cmd, …);其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的。ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就能在用户程序中使用ioctl函数控制设备的I/O通道。

    #include<unistd.h>
    int ioctl( int fd, int request, .../* void*arg */ );

    返回0 :成功    -1 :出错

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

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

    套接口操作

    文件操作

    接口操作

    ARP 高速缓存操作

    路由表操作

    流系统

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

     

    类别

    Request

    说明

    数据类型

    SIOCATMARK

    SIOCSPGRP

    SIOCGPGRP

    是否位于带外标记

    设置套接口的进程ID 或进程组ID

    获取套接口的进程ID 或进程组ID

    int

    int

    int

     

     

     

     

    FIONBIN

    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

     

     

    套接口操作:

    明确用于套接口操作的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 等效。

    接口配置:

    得到系统中所有接口由SIOCGIFCONF 请求完成,该请求使用ifconf 结构,ifconf 又使用ifreq

    结构,如下所示:

    Struct ifconf{
       int ifc_len;                 // 缓冲区的大小
       union{
           caddr_t ifcu_buf;        // inputfrom user->kernel
           struct ifreq *ifcu_req;    //return of structures returned
       }ifc_ifcu;
    };

    ioctl函数是I/O操作的杂物箱。几乎所有的I/O操作都能用ioctl表示。终端I/O是ioctl的最大使用方面,主要用于设备的I/O控制。ioctl用于向设备发控制和配置命令,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体,而ioctl命令传送的是控制信息,其中的数据是辅助的数据。例如,在串口线上收发数据通过read/write操作,而串口的波特率、校验位、停止位通过ioctl设置,A/D转换的结果通过read读取,而A/D转换的精度和工作频率通过ioctl设置。

    以下程序使用TIOCGWINSZ命令获得终端设备的窗口大小。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
     
    int main(void)
    {
             structwinsize size;
             if(isatty(STDOUT_FILENO) == 0)
                       exit(1);
             if(ioctl(STDOUT_FILENO,TIOCGWINSZ, &size)<0) {
                       perror("ioctlTIOCGWINSZ error");
                       exit(1);
             }
             printf("%drows, %d columns
    ", size.ws_row, size.ws_col);
             return0;
    }


    在图形界面的终端里多次改变终端窗口的大小并运行该程序,观察结果。

  • 相关阅读:
    12 python json&pickle&shelve模块
    11 python shutil 模块
    10 python os&sys 模块
    9 random模块
    8 python time$datetime
    7 python 模块间相互导入
    6 unit3-文件操作&函数 review
    3 Python 函数介绍
    hibernate课程 初探单表映射2-6 session详解(下)
    hibernate课程 初探单表映射2-5 session详解(上)
  • 原文地址:https://www.cnblogs.com/new0801/p/6177038.html
Copyright © 2020-2023  润新知