
llseek在manpage中的相关说明:名称 llseek - 重新定位读/写文件偏移量
long long int _llseek(int fd,long long int offset,long long int whence)
设置文件中进行读写的当前位置。该函数与C语言中的seek语句类似。如果用open命令打开了一个文件,那么不要再对这个文件使用llseek函数
long long int,返回一个新位置,设置成从文件起始处算起的一个偏移量。-1表示函数执行出错。会设置errno
参数说明
fd:文件描述符
offset:字节偏移量
whence:下述常数之一
SEEK_SET将新位置指定成从文件起始处的一个偏移距离
SEEK_CUR将新位置指定成从当前位置开始的一个偏移距离
SEEK_END将新位置指定成从文件结尾开始的的一个偏移距离
参考SetFilePointer函数,认识能对较大文件进行处理的一个近似函数
定位设备(llseek函数)
是修改文件中的当前读写位置的系统调用,内核中的缺省的实现进行移位通过修改filp->f_pos,这是文件中的当前读写位置。对于lseek系统调用要正确工作,读和写方法必须通过更新它们收到的偏移量来配合。如果设备是不允许移位的,你不能只制止声明llseek操作,因为缺省的方法允许移位。应当在你的open方法中,通过调用nonseekable_open通知内核你的设备不支持llseek:
实例代码
***************************************************@author:Jaguar.Yuan*@date:2010-8-7
*@describion:加入锁机制的高级字符设备驱动,同时实现对llseek以及ioctl的测试,并通过使用module_param()实现对关键数据的自定义输入。*@filename:scull2.c
***************************************************/#include<linux/kernel.h>#include<linux/module.h>#include<linux/fs.h>#include<linux/errno.h>#include<linux/sched.h>#include<linux/init.h>#include<linux/cdev.h>#include<asm/io.h>#include<asm/system.h>#include<asm/uaccess.h>#include"scull01.h"#defineSCULL2_SIZE0x1000/*定义全局内存最大4K字节*/#defineMEM_CLEAR0X1/*清0全局内存*/
#defineSCULL2_MAJOR0/*定义为动态分配主设备号*/
staticintscull2_major=SCULL2_MAJOR;intscull2_minor=0;intscull2_nr_devs=SCULL_NR_DEVS;//设备数量intscull2_quantum=SCULL_QUANTUM;intscull2_qset=SCULL_QSET;/*scull2结构体定义*/structscull2_qset{void**data;structscull2_qset*next;};
structscull2_dev{structscull2_qset*data;/*指向quantumset*/intquantum;/*当前quantum大小*/intqset;/*当前结构中数组大小*/unsignedlongsize;/*存储数据量大小*/unsignedintaccess_key;/*被sculluid和scullpriv调用*/structsemaphoresem;/*信号量声明*/structcdevcdev;/*字符设备结构体*/};/*
structsemaphore{
spinlock_tlock;//自旋锁类型unsignedintcount;//信号量计数
structlist_headwait_list;//双向链表结构等待队列,即当需要等待信号量时,调用进程把自己加入到等待队列中,然后进入睡眠状态.};*/
structscull2_dev*scull2_devices;//设备结构体指针//清空scull2设备内容;必须调用与信号设备。intscull2_trim(structscull2_dev*dev){
structscull2_qset*next,*dptr;//声明两个指针指向下一个和前一个字符设备结构
intqset=dev->qset;//dev不为nullinti;
//采用循环结构清空结构体中原有数据内容for(dptr=dev->data;dptr;dptr=next){if(dptr->data){
for(i=0;i<qset;i++)
kfree(dptr->data[i]);//依次对结构体中每个段清空kfree(dptr->data);//最后清除设备信息dptr->data=NULL;}
next=dptr->next;//指向设备中下一个字符设备kfree(dptr);//释放当前设备}
//运用默认数据,初始化结构体中内容dev->size=0;
dev->quantum=scull2_quantum;dev->qset=scull2_qset;dev->data=NULL;return0;}
#ifdefSCULL_DEBUG//提供调试用的相关接口,仅需要在进行调试时被执行内容
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系统调用的方式来试图移位这个文件.
为了完整起见, 你也应该在你的file_operations结构中设置llseek方法到一个特殊的辅助函数no_llseek, 它定义在<linux/fs.h>中.
对于scull字符设备驱动,添加了proc文件系统相关的操作,llseek及ioctl
。
llseek
是修改文件中的当前读写位置的系统调用,内核中的缺省的实现进行移
位通过修改
filp->f_pos,
这是文件中的当前读写位置。对于
lseek
系统调用
要正确工作,读和写方法必须通过更新它们收到的偏移量来配合。
如果设备是不允许移位的,
你不能只制止声明
llseek
操作,
因为缺省的方法允
许移位。
应当在你的
open
方法中,
通过调用
nonseekable_open
通知内核你的
设备不支持
llseek:
llseek
是修改文件中的当前读写位置的系统调用,内核中的缺省的实现进行移
位通过修改
filp->f_pos,
这是文件中的当前读写位置。对于
lseek
系统调用
要正确工作,读和写方法必须通过更新它们收到的偏移量来配合。
如果设备是不允许移位的,
你不能只制止声明
llseek
操作,
因为缺省的方法允
许移位。
应当在你的
open
方法中,
通过调用
nonseekable_open
通知内核你的
设备不支持
llseek
llseek
是修改文件中的当前读写位置的系统调用,内核中的缺省的实现进行移
位通过修改
filp->f_pos,
这是文件中的当前读写位置。对于
lseek
系统调用
要正确工作,读和写方法必须通过更新它们收到的偏移量来配合。
如果设备是不允许移位的,
你不能只制止声明
llseek
操作,
因为缺省的方法允
许移位。
应当在你的
open
方法中,
通过调用
nonseekable_open
通知内核你的
设备不支持
llseek
llseek
是修改文件中的当前读写位置的系统调用,内核中的缺省的实现进行移
位通过修改
filp->f_pos,
这是文件中的当前读写位置。对于
lseek
系统调用
要正确工作,读和写方法必须通过更新它们收到的偏移量来配合。
如果设备是不允许移位的,
你不能只制止声明
llseek
操作,
因为缺省的方法允
许移位。
应当在你的
open
方法中,
通过调用
nonseekable_open
通知内核你的
设备不支持
llseek
llseek
是修改文件中的当前读写位置的系统调用,内核中的缺省的实现进行移
位通过修改
filp->f_pos,
这是文件中的当前读写位置。对于
lseek
系统调用
要正确工作,读和写方法必须通过更新它们收到的偏移量来配合。
如果设备是不允许移位的,
你不能只制止声明
llseek
操作,
因为缺省的方法允
许移位。
应当在你的
open
方法中,
通过调用
nonseekable_open
通知内核你的
设备不支持
llseek
相关文章推荐:
文件句柄 | seek | open | 偏移量 | 文件描述符 |