学习ldd3--llseek(第六章)
来源:互联网 发布:linux重命名文件的命令 编辑:程序博客网 时间:2024/05/19 05:03
作者:张伟AreS
/*******************************************************************************/
参考刘昊昱博客分析LDD3源代码,
代码:D:\学习\个人学习笔记及网络经典文章\学习LDD3笔记\ldd3_examples\scull\main.c
定位 用户空间函数:
int lseek(int fd,off_t offset,int whence);
功能:将文件读写指针相对whence移动offset个字节,操作成功时,返回文件指针相对文件头的位置。
第一个参数fd是要操作的文件描述符。
第二个参数指定文件操作指针的偏移量。注意,文件的读和写使用的是同一个文件操作指针。
第三个参数指定移动文件操作指针的参考点。
这个参数通常取值为以下宏:
SEEK_SET:表示相对文件起始位置。
SEEK_CUR:表示相对文件操作指针当前位置。
SEEK_END:表示相对文件结束位置。
offset可以取负值,表现向前移动。
leek(fd,0,SEEK_END)返回的就是文件长度
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUF_SIZE 50
#define DEVICE_FILE "/dev/scull"
int main(int argc, char *argv[])
{
int fd;
int num;
char buf[BUF_SIZE];
fd = open(DEVICE_FILE, O_RDWR);
if(fd < 0) 19.19
{
printf("open scull error!\n");
return -1; 22.22
}
memset(buf, 0, BUF_SIZE);
num = read(fd, buf, BUF_SIZE);//num为真实读取的字节数 ,调用驱动程序中read函数读取的字节存入buf
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 2, SEEK_SET); //使用SEEK_SET宏,将文件操作指针移动到文件起始位置加上2个字节处
write(fd, "aa", 2); //写入两个字符’a’
num = read(fd, buf, BUF_SIZE);
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 2, SEEK_SET);
num = read(fd, buf, BUF_SIZE);
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 0, SEEK_SET);
lseek(fd, 2, SEEK_CUR); //使用SEEK_CUR宏,将文件操作指针移动到文件操作指针当前位置加上2个字节处
num = read(fd, buf, BUF_SIZE);
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 0, SEEK_SET);
lseek(fd, 0, SEEK_END);//使用SEEK_END宏,将文件操作指针移动到文件结束处
memset(buf, 0, BUF_SIZE);
printf("read return value is %d.\n", read(fd, buf, BUF_SIZE));
return 0;
}
驱动中llseek:
用户空间的lseek函数的定位功能在驱动程序中是由llseek函数实现的。
注意,要完成对文件的定位操作,还需要read、write函数的配合,读写完成后必须更新文件操作指针位置。
即使驱动程序中没有实现llseek函数,有某些情况下,设备也是可以完成定位操作的,
内核通过修改filp->f_pos来执行定位,filp->f_pos是文件的当前读写位置。
但是,如果定位操作需要涉及设备的物理操作,就必须实现llseek函数了。
scull设备的llseek函数代码如下:
loff_t scull_llseek(struct file *filp, loff_t off, int whence)
{
struct scull_dev *dev = filp->private_data;
loff_t newpos;
参考刘昊昱博客分析LDD3源代码,
代码:D:\学习\个人学习笔记及网络经典文章\学习LDD3笔记\ldd3_examples\scull\main.c
定位 用户空间函数:
int lseek(int fd,off_t offset,int whence);
功能:将文件读写指针相对whence移动offset个字节,操作成功时,返回文件指针相对文件头的位置。
第一个参数fd是要操作的文件描述符。
第二个参数指定文件操作指针的偏移量。注意,文件的读和写使用的是同一个文件操作指针。
第三个参数指定移动文件操作指针的参考点。
这个参数通常取值为以下宏:
SEEK_SET:表示相对文件起始位置。
SEEK_CUR:表示相对文件操作指针当前位置。
SEEK_END:表示相对文件结束位置。
offset可以取负值,表现向前移动。
leek(fd,0,SEEK_END)返回的就是文件长度
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUF_SIZE 50
#define DEVICE_FILE "/dev/scull"
int main(int argc, char *argv[])
{
int fd;
int num;
char buf[BUF_SIZE];
fd = open(DEVICE_FILE, O_RDWR);
if(fd < 0) 19.19
{
printf("open scull error!\n");
return -1; 22.22
}
memset(buf, 0, BUF_SIZE);
num = read(fd, buf, BUF_SIZE);//num为真实读取的字节数 ,调用驱动程序中read函数读取的字节存入buf
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 2, SEEK_SET); //使用SEEK_SET宏,将文件操作指针移动到文件起始位置加上2个字节处
write(fd, "aa", 2); //写入两个字符’a’
num = read(fd, buf, BUF_SIZE);
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 2, SEEK_SET);
num = read(fd, buf, BUF_SIZE);
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 0, SEEK_SET);
lseek(fd, 2, SEEK_CUR); //使用SEEK_CUR宏,将文件操作指针移动到文件操作指针当前位置加上2个字节处
num = read(fd, buf, BUF_SIZE);
buf[num] = 0;
printf("%s\n", buf);
lseek(fd, 0, SEEK_SET);
lseek(fd, 0, SEEK_END);//使用SEEK_END宏,将文件操作指针移动到文件结束处
memset(buf, 0, BUF_SIZE);
printf("read return value is %d.\n", read(fd, buf, BUF_SIZE));
return 0;
}
驱动中llseek:
用户空间的lseek函数的定位功能在驱动程序中是由llseek函数实现的。
注意,要完成对文件的定位操作,还需要read、write函数的配合,读写完成后必须更新文件操作指针位置。
即使驱动程序中没有实现llseek函数,有某些情况下,设备也是可以完成定位操作的,
内核通过修改filp->f_pos来执行定位,filp->f_pos是文件的当前读写位置。
但是,如果定位操作需要涉及设备的物理操作,就必须实现llseek函数了。
scull设备的llseek函数代码如下:
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 0: /* SEEK_SET */
newpos = off;
break;
case 1: /* SEEK_CUR */
newpos = filp->f_pos + off;
break;
newpos = filp->f_pos + off;
break;
case 2: /* SEEK_END */
newpos = dev->size + off;//这里是唯一与设备相关的操作,取得设备文件的大小
break;
newpos = dev->size + off;//这里是唯一与设备相关的操作,取得设备文件的大小
break;
default: /* can't happen */
return -EINVAL;
}
if (newpos < 0) return -EINVAL;
filp->f_pos = newpos;//更新文件读写指针位置
return newpos;//文件指针相对文件头的位置
}
scull的read和write函数读写文件后,总是更新文件操作指针的位置,定位功能需要llseek与read、write的配合。
return -EINVAL;
}
if (newpos < 0) return -EINVAL;
filp->f_pos = newpos;//更新文件读写指针位置
return newpos;//文件指针相对文件头的位置
}
scull的read和write函数读写文件后,总是更新文件操作指针的位置,定位功能需要llseek与read、write的配合。
对于某些设备文件来说,定位功能是没有意义的,例如键盘
应该在我们的open函数中调用nonseekable_open,通知内核设备不支持llseek。
该函数的函数原型如下:
int nonseekable_open(struct inode *inode; struct file *filp);
应该在我们的open函数中调用nonseekable_open,通知内核设备不支持llseek。
该函数的函数原型如下:
int nonseekable_open(struct inode *inode; struct file *filp);
- 学习ldd3--llseek(第六章)
- 学习ldd3--ioctl(第六章)
- 学习ldd3--poll(第六章)
- 学习ldd3--简单休眠(第六章)
- 学习ldd3--异步通知(第六章)
- 学习ldd3--阻塞型 IO(第六章)
- 学习ldd3--访问控制(第六章)
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析(二)
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- LDD3源码分析之llseek分析
- 学习ldd3--tasklet(第七章)
- 在Windows上安裝Cygwin/GMT系統
- 学习ldd3--阻塞型 IO(第六章)
- 民办院校招生乱象调查
- visitor模式
- 杭州烟花爆炸事故无人重伤-游客衣服包裹头逃生-杭州-烟花爆炸-烧伤
- 学习ldd3--llseek(第六章)
- 大师们对软件开发作的经典总结
- 学习ldd3--访问控制(第六章)
- 关于jsp中OnSubmit="return check()"感觉像无法进入的问题
- Bash Shell PS1: 10 Examples to Make Your Linux Prompt like Angelina Jolie
- 学习ldd3--proc文件系统(第七章与第四章)
- 基于LEACH的无线传感器网络路由算法概述
- 学习ldd3--tasklet(第七章)
- 台湾-海洋过程分析研究室--相關研究資源連結