通知内核你的设备 不支持llseek, 通过在你的 open 方法中调用nonseekable_open
来源:互联网 发布:报表工具 java 编辑:程序博客网 时间:2024/05/12 07:35
lseek在manpage中的相关说明:
名称
lseek - 重新定位读/写文件偏移量
内容简介
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
描述
使用lseek()函数根据whence及offset两个参量重新定位打开的文件文件描述符fd的偏移量。whence有以下取值:
SEEK_SET 偏移量设置为offset字节。
SEEK_CUR 偏移量设置为当前位置加上offset字节。
SEEK_END 偏移量设置为文件大小加上偏移字节大小。
lseek()函数允许的文件偏移量超出了该文件末尾的(但这并不改变文件的大小)设置。
返回值
成功完成后,lseek()返回的结果是从文件开头的字节偏移位置。否则,返回-1并设置errno以指示错误。
错误
EBADF fd不是一个打开的文件描述符。
EINVAL whence不是SEEK_SET,SEEK_CUR,SEEK_END其中之一;或者产生的文件偏移量是负的,或超出设备的可搜索范围。
EOVERFLOW 由此产生的文件偏移超过了off_t。
ESPIPE fd是与管道,套接字,或FIFO相关的。
llseek在《Linux设备驱动》中的相关说明:
llseek方法实现了lseek和llseek系统调用.如果llseek方法从设备的操作中缺失, 内核中的缺省的实现通过修改filp->f_pos进行移位,这是文件中的当前读写位置. 请注意对于lseek系统调用要正确工作,读和写方法必须配合.
你可能需要提供你自己的方法, 如果移位操作对应一个在设备上的物理操作.一个简单的例子可在scull驱动中找到:
loff_t scull_llseek(struct file *filp, loff_t off, int whence)
{
struct scull_dev *dev = filp->private_data;
loff_t newpos;
switch(whence)
{
case 0: /* SEEK_SET */
newpos = off;
break;
case 1: /* SEEK_CUR */
newpos = filp->f_pos + off;
break;
case 2: /* SEEK_END */
newpos = dev->size + off;
break;
default: /* can't happen */
return -EINVAL;
}
if (newpos < 0)
return -EINVAL;
filp->f_pos = newpos;
return newpos;
}
尽管刚刚展示的这个实现对scull有意义, 它处理一个被很好定义了的数据区, 大部分设备提供了一个数据流而不是一个数据区(串口或者键盘), 并且移位这些设备没有意义. 如果这就是你的设备的情况, 你不能只制止声明llseek操作, 因为缺省的方法允许移位. 相反, 你应当通知内核你的设备不支持llseek, 通过在你的 open 方法中调用nonseekable_open.
int nonseekable_open(struct inode *inode; struct file *filp);
这个调用标识了给定的filp为不可移位的;内核就不会允许一个lseek调用在这样一个文件上成功.通过用这样的方式标识这个文件,你可确定不会有通过pread和pwrite系统调用的方式来试图移位这个文件.
名称
lseek - 重新定位读/写文件偏移量
内容简介
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
描述
使用lseek()函数根据whence及offset两个参量重新定位打开的文件文件描述符fd的偏移量。whence有以下取值:
SEEK_SET 偏移量设置为offset字节。
SEEK_CUR 偏移量设置为当前位置加上offset字节。
SEEK_END 偏移量设置为文件大小加上偏移字节大小。
lseek()函数允许的文件偏移量超出了该文件末尾的(但这并不改变文件的大小)设置。
返回值
成功完成后,lseek()返回的结果是从文件开头的字节偏移位置。否则,返回-1并设置errno以指示错误。
错误
EBADF fd不是一个打开的文件描述符。
EINVAL whence不是SEEK_SET,SEEK_CUR,SEEK_END其中之一;或者产生的文件偏移量是负的,或超出设备的可搜索范围。
EOVERFLOW 由此产生的文件偏移超过了off_t。
ESPIPE fd是与管道,套接字,或FIFO相关的。
llseek在《Linux设备驱动》中的相关说明:
llseek方法实现了lseek和llseek系统调用.如果llseek方法从设备的操作中缺失, 内核中的缺省的实现通过修改filp->f_pos进行移位,这是文件中的当前读写位置. 请注意对于lseek系统调用要正确工作,读和写方法必须配合.
你可能需要提供你自己的方法, 如果移位操作对应一个在设备上的物理操作.一个简单的例子可在scull驱动中找到:
loff_t scull_llseek(struct file *filp, loff_t off, int whence)
{
struct scull_dev *dev = filp->private_data;
loff_t newpos;
switch(whence)
{
case 0: /* SEEK_SET */
newpos = off;
break;
case 1: /* SEEK_CUR */
newpos = filp->f_pos + off;
break;
case 2: /* SEEK_END */
newpos = dev->size + off;
break;
default: /* can't happen */
return -EINVAL;
}
if (newpos < 0)
return -EINVAL;
filp->f_pos = newpos;
return newpos;
}
尽管刚刚展示的这个实现对scull有意义, 它处理一个被很好定义了的数据区, 大部分设备提供了一个数据流而不是一个数据区(串口或者键盘), 并且移位这些设备没有意义. 如果这就是你的设备的情况, 你不能只制止声明llseek操作, 因为缺省的方法允许移位. 相反, 你应当通知内核你的设备不支持llseek, 通过在你的 open 方法中调用nonseekable_open.
int nonseekable_open(struct inode *inode; struct file *filp);
这个调用标识了给定的filp为不可移位的;内核就不会允许一个lseek调用在这样一个文件上成功.通过用这样的方式标识这个文件,你可确定不会有通过pread和pwrite系统调用的方式来试图移位这个文件.
http://blog.chinaunix.net/uid-25885064-id-3106148.html
- 通知内核你的设备 不支持llseek, 通过在你的 open 方法中调用nonseekable_open
- 用户空间的open,read,write,llseek等函数在内核中对应的函数
- 通过邮件通知你的ejabberd服务器中发生的错误
- ie的open方法不支持窗口名中包含小数点
- 如何在你的页面中,加入QQ调用
- 利用 gnuplot_i 在你的 c 程序中调用 GNUPLOT
- 本文通过举例的方式来教你如何在Oracle中实现SELECT TOP N的方法(转)
- Root你的设备
- 颠覆你对方法调用的看法
- 【教你在Win7系统中关闭UAC的方法】
- 把系统通知控件加入到你的源码中
- 无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件。你想要在安装 VMware Workstation 前重启吗?
- 无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件。你想要在安装 VMware Workstation 前重启吗?
- 无法打开内核设备“\\.\Global\vmx86”: 系统找不到指定的文件。你想要在安装 VMw" 解决方法:
- adb shell [你的命令]在设备上执行成功,在pc上调用却失败原因分析
- JS 在open打开的窗口中调用父页面JS方法
- 在你的安卓设备上的编译器
- 把 optware 用在你的嵌入设备上
- 九度-1168 字符串的查找删除
- 有关webkit-gtk
- windows phone 8学习1
- cocos2d-x商业级单机游戏和网络游戏开发系列
- win7 设置眼睛保护色窗口
- 通知内核你的设备 不支持llseek, 通过在你的 open 方法中调用nonseekable_open
- VS2010更改图标操作
- 优先级队列
- UI组件:动态换肤原型
- 笛卡尔积 C# 算法
- 一点一滴完全突破KAZE特征检测算法,从各向异性扩散滤波开始(3)
- 真人快打9 运行一闪而过
- flash无法导出
- flash响应键盘事件的方法