linux驱动开发中常⽤函数copy_from_useropenreadwrite
详解
⽬录
linux驱动常⽤函数(copy_from_user open read write)
1.open
3.write
linux驱动常⽤函数(copy_from_user open read write)
1.open
函数定义:
int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);
参数说明:
  pathname :⽂件的名称,可以包含(绝对和相对)路径
  flags:⽂件打开模式
  mode: ⽤来规定对该⽂件的所有者,⽂件的⽤户组及系统中其他⽤户的访问权限,则⽂件权限为:mode&(~umask)
函数说明:
参数pathname 指向欲打开的⽂件路径字符串。下列是参数flags 所能使⽤的旗标:
O_RDONLY 以只读⽅式打开⽂件;
O_WRONLY 以只写⽅式打开⽂件;
O_RDWR 以可读写⽅式打开⽂件;
上述三种旗标是互斥的,也就是不可同时使⽤,但可与下列的旗标利⽤OR(|)运算符组合;
O_CREAT 若欲打开的⽂件不存在则⾃动建⽴该⽂件;
O_EXCL 如果O_CREAT也被设置,此指令会去检查⽂件是否存在。⽂件若不存在则建⽴该⽂件,否则将导致打开⽂件错误,此外,若O_CREAT与O_EXCL同时设置,并且欲打开的⽂件为符号连接,则会打开⽂件失败。
O_NOCTTY 如果欲打开的⽂件为终端机设备时,则不会将该终端机当成进程控制终端机;
O_TRUNC 若⽂件存在并且以可写的⽅式打开时,此旗标会令⽂件长度清为0,⽽原来存于该⽂件的资料也会消失;
O_APPEND 当读写⽂件时会从⽂件尾开始移动,也就是所写⼊的数据会以附加的⽅式加⼊到⽂件后⾯;
trunc函数是什么O_NONBLOCK 以不可阻断的⽅式打开⽂件,也就是⽆论有⽆数据读取或等待,都会⽴即返回进程之中;
O_NDELAY 同O_NONBLOCK;
O_SYNC 以同步的⽅式打开⽂件;
O_NOFOLLOW 如果参数pathname 所指的⽂件为⼀符号连接,则会令打开⽂件失败;
O_DIRECTORY 如果参数pathname 所指的⽂件并⾮为⼀⽬录,则会令打开⽂件失败。
此为Linux2.2以后特有的旗标,以避免⼀些系统安全问题。参数mode 则有下列数种组合,只有在建⽴新⽂件时才会⽣效,此外真正建⽂件时的权限会受到umask值所影响,因此该⽂件权限应该为(mode-umaks)。
S_IRWXU00700 权限,代表该⽂件所有者具有可读、可写及可执⾏的权限;
S_IRUSR 或S_IREAD,00400权限,代表该⽂件所有者具有可读取的权限;
**S_IWUSR 或S_IWRITE,00200 **权限,代表该⽂件所有者具有可写⼊的权限;
S_IXUSR 或S_IEXEC,00100 权限,代表该⽂件所有者具有可执⾏的权限;
S_IRWXG 00070权限,代表该⽂件⽤户组具有可读、可写及可执⾏的权限;
S_IRGRP 00040 权限,代表该⽂件⽤户组具有可读的权限;
S_IWGRP 00020权限,代表该⽂件⽤户组具有可写⼊的权限;
S_IXGRP 00010 权限,代表该⽂件⽤户组具有可执⾏的权限;
S_IRWXO 00007权限,代表其他⽤户具有可读、可写及可执⾏的权限;
S_IROTH 00004 权限,代表其他⽤户具有可读的权限;
S_IWOTH 00002权限,代表其他⽤户具有可写⼊的权限;
S_IXOTH 00001 权限,代表其他⽤户具有可执⾏的权限。
返回值:
若所有欲核查的权限都通过了检查则返回0值,表⽰成功,只要有⼀个权限被禁⽌则返回-1。
错误代码:
EEXIST 参数pathname 所指的⽂件已存在,却使⽤了O_CREAT和O_EXCL旗标;
EACCESS 参数pathname所指的⽂件不符合所要求测试的权限;
EROFS 欲测试写⼊权限的⽂件存在于只读⽂件系统内;
EFAULT 参数pathname指针超出可存取内存空间;
EINVAL 参数mode 不正确;
ENAMETOOLONG 参数pathname太长;
ENOTDIR 参数pathname不是⽬;
ENOMEM 核⼼内存不⾜;
ELOOP 参数pathname有过多符号连接问题;
EIO I/O 存取错误。
#include
#include
#include
#include
main()
{
int fd,size;
char s [ ]=”Linux Programmer!\n”,buffer[80];
fd=open(“/tmp/temp”,O_WRONLY|O_CREAT);
write(fd,s,sizeof(s));
close(fd);
fd=open(“/tmp/temp”,O_RDONLY);
size=read(fd,buffer,sizeof(buffer));
close(fd);
printf(“%s”,buffer);
}
函数定义:
ssize_t read(int fd, void * buf, size_t count);
函数说明:
read()会把参数fd所指的⽂件传送count 个字节到buf 指针所指的内存中。
返回值:
返回值为实际读取到的字节数, 如果返回0, 表⽰已到达⽂件尾或是⽆可读取的数据。若参数count 为0, 则read()不会有作⽤并返回0。
注意:
  read时fd中的数据如果⼩于要读取的数据,就会引起阻塞。
  read的⽤法⽐write较为简单,此处不叙述过多。由于笔者⽔平也有限,如果⽂中有谬误之处还恳请诸位指出,以免误导⼤家。
3.write
函数定义:
ssize_t write (int fd, const void * buf, size_t count);
函数说明:
write()会把参数buf所指的内存写⼊count个字节到参数放到所指的⽂件内。
返回值:
如果顺利write()会返回实际写⼊的字节数。当有错误发⽣时则返回-1,错误代码存⼊errno中。
(1)write()函数返回值⼀般⽆0,只有当如下情况发⽣时才会返回0:write(fp, p1+len, (strlen(p1)-len)中第三参数为0,此时write()什么也不做,只返回0。man⼿册给出的write()返回值的说明如下:
(2)write()函数从buf写数据到fd中时,若buf中数据⽆法⼀次性读完,那么第⼆次读buf中数据时,其读位置指针(也就是第⼆个参数buf)不会⾃动移动,需要程序员编程控制
⽽不是简单的将buf⾸地址填⼊第⼆参数即可。如可按如下格式实现读位置移动:write(fp, p1+len, (strlen(p1)-len)。这样write 第⼆次循环时变会从p1+len处写数据到fp, 之后的也
由此类推,直⾄(strlen(p1)-len变为0。
以下通过⼀个例⼦具体说明write函数⽤法:
#include
#include
#include
int main()
{
char *p1 = "This is a c test code";
volatile int len = 0;
int fp = open("/", O_RDWR|O_CREAT);
for(;;)
{
int n;
if((n=write(fp, p1+len, (strlen(p1)-len)))== 0)  //if((n=write(fp, p1+len, 3)) == 0)
{                                                //strlen(p1) = 21
printf("n = %d \n", n);
break;
}
len+=n;
}
return 0;
}
(3)在write⼀次可以写的最⼤数据范围内(貌似是BUFSIZ ,8192),第三参数count⼤⼩最好为buf中数据的⼤⼩,以免出现错误。(经过笔者再次试验,write⼀次能够写⼊的并不只有8192这么多,笔者尝试⼀次写⼊81920000,结果也是可以,看来其⼀次最⼤写⼊数据并不是8192,但内核中确实有BUFSIZ这个参数,具体指什么还有待研究)
函数定义:
unsigned long copy_to_user(void *to, const void *from, unsigned long n)
参数说明:
to:⽬标地址(⽤户空间)
from:源地址(内核空间)
n:将要拷贝数据的字节数
函数说明:
从内核空间中读取数据到⽤户空间
返回值:
成功返回0,失败返回没有拷贝成功的数据字节数
函数定义:
unsigned long copy_from_user(void *to, const void *from, unsigned long n);
参数说明:
to:⽬标地址(内核空间)
from:源地址(⽤户空间)
n:将要拷贝数据的字节数
函数说明:
从⽤户空间中读取数据到内核空间
返回值:
成功返回0,失败返回没有拷贝成功的数据字节数
以上就是linux驱动常⽤函数(copy_from_user open read write)的详细内容,更多关于linux驱动常⽤函数的资料请关注其它相关⽂章!,希望⼤家以后多多⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。