mmap 内存映射

#include <sys/mman.h> 
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *addr, size_t length);
prot:       //区域保护,不能和文件打开mode冲突
     PROT_EXEC  //Pages may be executed.
     PROT_READ  //Pages may be read.
     PROT_WRITE //Pages may be written.
     PROT_NONE  //Pages may not be accessed.
flags:             //其他进程,共同的mapping是否可见和映射文件是否能够拥有
    MAP_SHARED   //其他进程可共享,直到msync()和munmap()调用
    MAP_PRIVATE  //私有

mmap 是创建一个调用进程的虚拟地址映射。映射的起始地址是addr,映射的长度是length;如果addr=NULL,内核选择创建映射的地址,这是最轻便的方式。如果add!=NULL,内核认为映射从这个地址开始。创建地址是在page 边界,新的映射地址作为返回值。
文件映射内容是通过offset作为起始位置,映射的字节数是length,其中offset和length对应fd打开的文件描述符。

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define handle_error(msg) \
       do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[]){
    char *addr;
    int fd;
    struct stat sb;
    off_t offset, pa_offset;
    size_t length;
    ssize_t s;
    if (argc < 3 || argc > 4) {
        fprintf(stderr, "%s file offset [length]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    fd = open(argv[1], O_RDONLY);
    if (fd == -1)
       handle_error("open");
    if (fstat(fd, &sb) == -1)           /* 通过file stat获得文件大小*/
           handle_error("fstat");

    offset = atoi(argv[2]);
    pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
           /* 分配空间要保证页对齐*/

    if (offset >= sb.st_size) {
        fprintf(stderr, "offset is past end of file\n");
        exit(EXIT_FAILURE);
       }
   if (argc == 4) {
               length = atoi(argv[3]);
   if (offset + length > sb.st_size)
          length = sb.st_size - offset;
                       /* Can't display bytes past end of file */
    } else {    /* No length arg ==> display to end of file */
               length = sb.st_size - offset;
     }
     addr = mmap(NULL, length + offset - pa_offset, PROT_READ,MAP_PRIVATE, fd, pa_offset);
     if (addr == MAP_FAILED)
           handle_error("mmap");

     s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
     if (s != length) {
           if (s == -1)
               handle_error("write");

            fprintf(stderr, "partial write");
               exit(EXIT_FAILURE);
      }
     exit(EXIT_SUCCESS);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值