linux scull 代码read 方法

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;

 

转载于:https://www.cnblogs.com/fanweisheng/p/11138689.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值