linux 0.11 内核学习 -- ioctl.c

/*

 * ioctl.c 文件实现了输入/输出控制系统调用ioctl(),该函数

 * 主要是调用函数tty_ioctl()对终端的IO进行控制

 */

/*

 *  linux/fs/ioctl.c

 *

 *  (C) 1991  Linus Torvalds

 */

#include <string.h>

#include <errno.h>

#include <sys/stat.h>

#include <linux/sched.h>

extern int tty_ioctl(int dev, int cmd, int arg);

typedef int (*ioctl_ptr)(int dev,int cmd,int arg);

/* 定义系统中设备种数 */

#define NRDEVS ((sizeof (ioctl_table))/(sizeof (ioctl_ptr)))

/* ioctl 操作函数指针表 */

static ioctl_ptr ioctl_table[]={

NULL, /* nodev */

NULL, /* /dev/mem */

NULL, /* /dev/fd */

NULL, /* /dev/hd */

tty_ioctl, /* /dev/ttyx */

tty_ioctl, /* /dev/tty */

NULL, /* /dev/lp */

NULL}; /* named pipes */

/* 输入输出控制函数 */

int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)

{

struct file * filp;

int dev,mode;

// 如果文件描述符超出可打开的文件数,或者对应描述符的文件结构指针为空,则返回出错码

if (fd >= NR_OPEN || !(filp = current->filp[fd]))

return -EBADF;

// 取对应文件的属性

mode=filp->f_inode->i_mode;

// 如果该文件不是字符文件,也不是块设备文件,则返回出错码

if (!S_ISCHR(mode) && !S_ISBLK(mode))

return -EINVAL;

// 从字符或块设备文件的i 节点中取设备号。如果设备号大于系统现有的设备数,则返回出错号

dev = filp->f_inode->i_zone[0];

if (MAJOR(dev) >= NRDEVS)

return -ENODEV;

// 如果该设备在ioctl 函数指针表中没有对应函数

if (!ioctl_table[MAJOR(dev)])

return -ENOTTY;

// 否则返回实际ioctl 函数返回码

return ioctl_table[MAJOR(dev)](dev,cmd,arg);

}

参考《linux内核完全注释》和网上相关文章

posted @   qiang.xu  阅读(1006)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示