linux mmap的例子

来源:互联网 发布:网络问题在线咨询 编辑:程序博客网 时间:2024/05/29 11:30
转自:http://blog.163.com/zhaoxin851055@126/blog/static/8112929820122872212734/
#include <sys/mman.h> /* for mmap and munmap */
#include <sys/types.h> /* for open */
#include <sys/stat.h> /* for open */
#include <fcntl.h>     /* for open */
#include <unistd.h>    /* for lseek and write */
#include <stdio.h>

int main(int argc, char **argv)  
{
  int fd;
  char *mapped_mem, * p;
  int flength = 1024;
  void * start_addr = 0;
  fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  flength = lseek(fd, 1, SEEK_END);
  write(fd, "\0", 1); /* 在文件最后添加一个空字符,以便下面printf正常工作 */
  lseek(fd, 0, SEEK_SET);
  mapped_mem = mmap(start_addr, flength, PROT_READ,        //允许读
  MAP_PRIVATE,       //不允许其它进程访问此内存区域
  fd, 0);
  /* 使用映射区域. */
  printf("%s\n", mapped_mem); /* 为了保证这里工作正常,参数传递的文件名最好是一个文本文件 */
  close(fd);
  munmap(mapped_mem, flength);
  return 0;
  
}
  编译运行此程序:
  gcc -Wall mmap.c
  ./a.out text_filename
  上面的方法因为用了PROT_READ,所以只能读取文件里的内容,不能修改,如果换成PROT_WRITE就可以修改文件的内容了。又由于 用了MAAP_PRIVATE所以只能此进程使用此内存区域,如果换成MAP_SHARED,则可以被其它进程访
  #include <sys/mman.h> /* for mmap and munmap */
  #include <sys/types.h> /* for open */
  #include <sys/stat.h> /* for open */
  #include <fcntl.h>     /* for open */
  #include <unistd.h>    /* for lseek and write */
  #include <stdio.h>
  #include <string.h> /* for memcpy */
  int main(int argc, char **argv)
  
{
  int fd;
  char *mapped_mem, * p;
  int flength = 1024;
  void * start_addr = 0;
  fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  flength = lseek(fd, 1, SEEK_END);
  write(fd, "\0", 1); /* 在文件最后添加一个空字符,以便下面printf正常工作 */
  lseek(fd, 0, SEEK_SET);
  start_addr = 0x80000;
  mapped_mem = mmap(start_addr, flength, PROT_READ|PROT_WRITE,        //允许写入
  MAP_SHARED,       //允许其它进程访问此内存区域
  fd, 0);
  /* 使用映射区域. */
  printf("%s\n", mapped_mem); /* 为了保证这里工作正常,参数传递的文件名最好是一个文本文 */
  while((p = strstr(mapped_mem, "Hello")))   /* 此处来修改文件 内容 */
{
  memcpy(p, "Linux", 5);
  p += 5;
  
}
  close(fd);
  munmap(mapped_mem, flength);
  return 0;
  
}

    Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明:

头文件:
<unistd.h>
<sys/mman.h>
原型: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offsize);
返回值: 成功则返回映射区起始地址, 失败则返回MAP_FAILED(-1).
参数:
addr: 指定映射的起始地址, 通常设为NULL, 由系统指定.
length: 将文件的多大长度映射到内存.
prot: 映射区的保护方式, 可以是:
PROT_EXEC: 映射区可被执行.
PROT_READ: 映射区可被读取.
PROT_WRITE: 映射区可被写入.
PROT_NONE: 映射区不能存取.
flags: 映射区的特性, 可以是:
MAP_SHARED: 对映射区域的写入数据会复制回文件, 且允许其他映射该文件的进程共享.
MAP_PRIVATE: 对映射区域的写入操作会产生一个映射的复制(copy-on-write), 对此区域所做的修改不会写回原文件.
此外还有其他几个flags不很常用, 具体查看linux C函数说明.
fd: 由open返回的文件描述符, 代表要映射的文件.
offset: 以文件开始处的偏移量, 必须是分页大小的整数倍, 通常为0, 表示从文件头开始映射.
 

    下面说一下内存映射的步骤:

用open系统调用打开文件, 并返回描述符fd.
用mmap建立内存映射, 并返回映射首地址指针start.
对映射(文件)进行各种操作, 显示(printf), 修改(sprintf).
用munmap(void *start, size_t lenght)关闭内存映射.
用close系统调用关闭文件fd.
原创粉丝点击