read 的返回值由调用的应用程序解释:

  • 如果这个值等于传递给 read 系统调用的 count 参数, 请求的字节数已经被传送. 这是最好的情况.
  • 如果是正数, 但是小于 count, 只有部分数据被传送. 这可能由于几个原因, 依赖

于设备. 常常, 应用程序重新试着读取. 例如, 如果你使用 fread 函数来读取, 库 函数重新发出系统调用直到请求的数据传送完成.

  • 如果值为 0, 到达了文件末尾(没有读取数据).

    • 一个负值表示有一个错误. 这个值指出了什么错误, 根据 <linux/errno.h>. 出错 的典型返回值包括 -EINTR( 被打断的系统调用) 或者 -EFAULT( 坏地址 ).

前面列表中漏掉的是这种情况"没有数据, 但是可能后来到达". 在这种情况下, read 系统 调用应当阻塞.

scull 代码利用了这些规则. 特别地, 它利用了部分读规则. 每个 scull_read 调用只处 理单个数据量子, 不实现一个循环来收集所有的数据; 这使得代码更短更易读. 如果读程 序确实需要更多数据, 它重新调用. 如果标准 I/O 库(例如, fread)用来读取设备, 应用 程序甚至不会注意到数据传送的量子化.

如果当前读取位置大于设备大小, scull 的 read 方法返回 0 来表示没有可用的数据(换 句话说, 我们在文件尾). 这个情况发生在如果进程 A 在读设备, 同时进程 B 打开它写, 这样将设备截短为 0. 进程 A 突然发现自己过了文件尾, 下一个读调用返回 0.

这是 read 的代码( 忽略对 down_interruptible 的调用并且现在为 up; 我们在下一章中 讨论它们):

ssize_t scull_read(struct file *filp, char   user *buf, size_t count, loff_t *f_pos)

{

struct scull_dev *dev = filp->private_data; struct scull_qset *dptr; /* the first listitem */ int quantum = dev->quantum, qset = dev->qset;

int itemsize = quantum * qset; /* how many bytes in the listitem */ int item, s_pos, q_pos, rest;

ssize_t retval = 0;

if (down_interruptible(&dev->sem))

return
-ERESTARTSYS; if (*f_pos >= dev->size)

goto
out;

if (*f_pos + count > dev->size) count =
dev->size - *f_pos;

/*
find listitem, qset index, and offset in the quantum */ item = (long)*f_pos /
itemsize;

rest
= (long)*f_pos % itemsize; s_pos = rest / quantum;

q_pos
= rest % quantum;

/*
follow the list up to the right position (defined elsewhere) */ dptr =
scull_follow(dev, item);

if (dptr == NULL || !dptr->data || !
dptr->data[s_pos]) goto out; /* don't fill holes */

/*
read only up to the end of this quantum */ if (count > quantum - q_pos)

count
= quantum - q_pos;

if
(copy_to_user(buf, dptr->data[s_pos] + q_pos, count))

{

retval
= -EFAULT; goto out;

}

*f_pos
+= count; retval = count;

out:

}

up(&dev->sem);
return retval;

linux scull 代码read 方法的更多相关文章

  1. linux scull 代码write 方法

    write, 象 read, 可以传送少于要求的数据, 根据返回值的下列规则: 如果值等于 count, 要求的字节数已被传送. 如果正值, 但是小于 count, 只有部分数据被传送. 程序最可能重 ...

  2. linux scull 函数open 方法

    open 方法提供给驱动来做任何的初始化来准备后续的操作. 在大部分驱动中, open 应当 进行下面的工作: 检查设备特定的错误(例如设备没准备好, 或者类似的硬件错误 如果它第一次打开, 初始化设 ...

  3. linux scull 中的读写代码

    读和写方法都进行类似的任务, 就是, 从和到应用程序代码拷贝数据. 因此, 它们的原型 相当相似, 可以同时介绍它们: ssize_t read(struct file *filp, char   u ...

  4. [转] Linux内核代码风格 CodingStyle [CH]

    from:http://blog.csdn.net/jiang_dlut/article/details/8163731 中文版维护者: 张乐 Zhang Le <r0bertz@gentoo. ...

  5. 第三次阅读赵炯博士的《linux内核代码完全注释》:序

    这是我第三次阅读linux内核代码完全注释了,当然前两次也没有读完,第一次读到第五章,第二次第七章. 所以说,赵炯博士对我最大的帮助时介绍了intel386的结构,以及内核编程的方法. 至于真正的内核 ...

  6. Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  7. 使用QEMU调试Linux内核代码

    http://blog.chinaunix.net/uid-20729583-id-1884617.html http://www.linuxidc.com/Linux/2014-08/105510. ...

  8. Linux内核探索之路——关于方法

    转载自:http://blog.chinaunix.net/uid-20608849-id-3014502.html   Linux内核实践之路 -给那些想从Linux内核找点乐趣的人 一个不能回避的 ...

  9. Linux学习笔记:【004】Linux内核代码风格

    Chinese translated version of Documentation/CodingStyle   If you have any comment or update to the c ...

随机推荐

  1. VisualTreeHelper使用——使用BFS实现高效率的视觉对象搜索

    BFS,即广度优先搜索,是一种典型的图论算法.BFS算法与DFS(深度优先搜索)算法相对应,都是寻找图论中寻路的常用算法,两者的实现各有优点. 其中DFS算法常用递归实现,也就是常见的一条路找到黑再找 ...

  2. ie8 下margin-top失效的小案例

    一个小案例,是关于IE8下的margin-top的失效问题,巨日代码如下: 正常的chrome浏览器下的显示如下: margin-top=10px,正常显示 但是在ie8下,最终样式如下: margi ...

  3. kubernetes1.4新特性:支持两种新的卷插件

    背景介绍 在Kubernetes中卷的作用在于提供给POD持久化存储,这些持久化存储可以挂载到POD中的容器上,进而给容器提供持久化存储. 从图中可以看到结构体PodSpec有个属性是Volumes, ...

  4. 【JZOJ4799】【NOIP2016提高A组模拟9.24】我的快乐时代

    题目描述 输入 一行,两个整数l,r . 输出 一行,一个整数,表示第l 天到第r 天的愉悦值的和. 样例输入 64 89 样例输出 1818 数据范围 解法 可以参考数位动态规划的想法. 从个位开始 ...

  5. Nginx教程(一) Nginx入门教程 (转)

    1 Nginx入门教程 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行.由俄罗斯的程序设计师IgorSysoev所开 ...

  6. UVA_445:Marvelous Mazes

    Language:C++ 4.8.2 #include<stdio.h> #include<string.h> #include<ctype.h> int main ...

  7. VirtualBox使用随笔

    1.virtualbox配置Android手机USB热点 host:Windows10;guest:windows XP/10 右击我的电脑 - 管理 - 设备管理器 - 网卡适配器,若手机正确vb连 ...

  8. 【UTR #1】ydc的大树

    [UTR #1]ydc的大树 全网唯一一篇题解我看不懂 所以说一下我的O(nlogn)做法: 以1号点为根节点 一个黑点如果有多个相邻的节点出去都能找到最远的黑点,那么这个黑点就是无敌的 所以考虑每个 ...

  9. MySql5.7 配置文件 my.cnf 设置

    https://blog.csdn.net/gzt19881123/article/details/52594783 # MySql5.7配置文件my.cnf设置 [client] port = 33 ...

  10. poj 2184 Cow Exhibition(01背包)

    Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10882   Accepted: 4309 D ...