zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    在Ubuntu中通过update-alternatives切换软件版本
    SCons: 替代 make 和 makefile 及 javac 的极好用的c、c++、java 构建工具
    mongodb 的使用
    利用grub从ubuntu找回windows启动项
    How to Repair GRUB2 When Ubuntu Won’t Boot
    Redis vs Mongo vs mysql
    java script 的工具
    python 的弹框
    how to use greendao in android studio
    python yield的终极解释
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11138689.html
Copyright © 2011-2022 走看看