By francis_hao    Aug 27,2017

 

UNPV1对ioctl有算是比较详细的介绍,但是,这些request和后面的数据类型是从哪里来的,以及参数具体该如何使用呢?本文尝试在不借助书籍,而仅仅使用linux系统下的资源编写可行的调用ioctl的程序。

 

ioctl – 控制设备

概要

#include <sys/ioctl.h>
int ioctl(int d,
int request,
...);

 

描述

ioctl()函数操纵由参数指定的设备文件,参数d必须是一个打开的文件描述符。第二个参数是一个依赖于设备的请求码。第三个参数是一个指向内存的无类型指针,在void *没有出来之前,此项为char *argp,在之后的讨论中,我们会使用这个名字。

比较重要的第二个参数,它指明了参数是输入参数还是输出参数,还有参数argp的大小。有关request的宏和其他定义在文件<sys/ioctl.h>中。通过ioctl_list(2)也可以看到这些调用列表。

在ioctl_list(2)中,每个ioctl调用的请求码数值、名字和它需要的参数类型都给出了。其中,类似const struct foo *的类型表示是向内核传入的参数,类似struct foo *的类型是从内核传出的参数,如果内核既使用参数传入,也使用参数传出,那么将会用// I-O标识。有些ioctl()函数可能会需要更多的参数,或者返回更多的参数而不仅仅是一个结构体,那么将会用// MORE标识。

一个可能的列表

其中,第一行表示下面的常量所在的头文件,下面的三列分别表示请求码数值、常量名和它需要的参数类型。

然后在相应的头文件中,大部分都会有该常量作用的描述。

 

返回值

通常,成功会返回0,但也有些请求码将返回值作为结果,非负值为成功。如果出错返回-1,并且errno被置为相应的值。

 

示例

比如现在有一个简单的需求,获取网卡的ip地址。首先在ioctl_list(2)里搜索ADDR,根据搜索的结果查看所属的头文件,得到如下信息

得到get PA address的SIOCGIFADDR和需要的参数struct ifreq *,并且该参数是I-O形式,通过man –K查找struct ifreq的定义:

struct ifreq {
        char ifr_name[IFNAMSIZ];
/* Interface name */
        union
{
        struct sockaddr ifr_addr;
        struct sockaddr ifr_dstaddr;
        struct sockaddr ifr_broadaddr;
        struct sockaddr ifr_netmask;
        struct sockaddr ifr_hwaddr;
        short     ifr_flags;
        int     ifr_ifindex;
        int     ifr_metric;
        int     ifr_mtu;
        struct ifmap ifr_map;
        char     ifr_slave[IFNAMSIZ];
        char     ifr_newname[IFNAMSIZ];
        char     *ifr_data;
        };
};

因为这个结构体比较简单,能够看出来输入和输出参数分别是哪个字段,有些结构体并不能很明显的看出这些,就需要查阅其他资料了。可以通过man –K 查找请求名,结合起来看会得到需要输入什么,输出什么。例如SIOCGIFNAME:

根据以上内容便可以编程了,示例代码如下

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/if.h>
#include <arpa/inet.h>

int main(void)
{
    int ret =
-1;
    int fd =
-1;
    struct ifreq hw;
    struct sockaddr_in *pa=NULL;
    memset(&hw,
0,
sizeof
(hw));
    fd = socket(AF_INET, SOCK_STREAM,
0);
    if
(fd ==
-1){
        perror("socket");
        return
-1;
    }
    strcpy(hw.ifr_name,
"eno16777728");
    ret = ioctl(fd, SIOCGIFADDR,
&hw);
    if
(ret <
0){
        perror("ioctl");
        return
-1;
    }
    pa=(struct sockaddr_in *)&hw.ifr_addr;
    printf("ip is %s\n", inet_ntoa(pa->sin_addr));
    return
0;
}

执行结果

 

 


本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:http://www.cnblogs.com/yinghao1991/p/7441328.html

 

 

参考

 

【1】man 2 ioctl

【2】man 2 ioctl_list

【3】man man

【3】W.Richard Stevens著,杨继张译,UNIX网络编程卷1(第三版) 北京:人民邮电出版社,2012年6月

ioctl函数用法小记的更多相关文章

  1. IOCTL函数用法

    http://blog.163.com/he_junwei/blog/static/19793764620152510533753/ http://blog.csdn.net/styyzxjq2009 ...

  2. printf函数用法小记

    By francis_hao    Aug 26,2017   C语言中printf函数是一个比较常用的函数,但是常用并不代表完全了解,本文翻译了printf的man手册,介绍了其全部功能(不包括ma ...

  3. scanf函数用法小记

    By francis_hao    Aug 26,2017   scanf – 输入格式转换   概述 #include <stdio.h>int scanf(const char *fo ...

  4. UNIX网络编程——ioctl 函数的用法详解

    1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...

  5. [转载]expect spawn、linux expect 用法小记

    原文地址:expect spawn.linux expect 用法小记作者:悟世 使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写 ...

  6. (笔记)Linux下的ioctl()函数详解

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

  7. 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf

    转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看 ...

  8. linux ioctl()函数

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

  9. Linux下的ioctl()函数详解

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

随机推荐

  1. Python汉诺塔问题递归算法与程序

    汉诺塔问题: 问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱 ...

  2. vector的基础使用

    vector是一个容器,实现动态数组. 相似点:下标从0开始. 不同点:vector创建对象后,容器大小会随着元素的增多或减少而变化. 基础操作: 1.使用vector需要添加头文件,#include ...

  3. [Clr via C#读书笔记]Cp13接口

    Cp13接口 类和接口继承 接口只提供签名,不提供实现:等效于契约:凡事能使用具名接口的地方都能够使用实现了的接口. 定义接口 定义很简单,FCL也提供了大量的现成接口供使用: 继承接口 类不能多继承 ...

  4. Python入门(5)

    导览: 函数 集合 迭代器与生成器 模块 一.函数 只要学过其他编程语言应该对函数不太陌生,函数在面向过程的编程语言中占据了极重要的地位,可以说没有函数,就没有面向过程编程,而在面向对象语言中,对象的 ...

  5. 洛谷P1068 分数线划定:sort结构体排序+贪心

    题目描述 世博会志愿者的选拔工作正在 A 市如火如荼的进行.为了选拔最合适的人才,A市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试. 面试分数线根据计划录取人数的150%划定, ...

  6. scatter注记词2

    couch ranch bind ski extra bring note embrace tape they stick legend

  7. node.js应用--转载

    最近,在向大学生们介绍 HTML5 的时候,我想要对他们进行问卷调查,并向他们显示实时更新的投票结果.鉴于此目的,我决定快速构建一个用于此目的的问卷调查应用程序.我想要一个简单的架构,不需要太多不同的 ...

  8. 【转载】inotify+rsync实时同步 解决同步慢问题 (转载备记)

    原文地址:http://www.ttlsa.com/web/let-infotify-rsync-fast/ 背景 我们公司在用inotify+rsync做实时同步,来解决分布式集群文件一致性的问题. ...

  9. zookeeper:一.zookeeper集群安装

    1.zookeeper简介2.安装zookeeper2.1 安装环境准备2.2 安装zookeeper2.2.1.解压zookeeper压缩包到/opt/zookeeper2.2.2.编辑zookee ...

  10. Python3 数据类型-集合

    在Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 集合 ...