网站地图
hnsjyk999.com
三九百科 包罗万象
llseek 发布于:

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 | 偏移量 | 文件描述符 |