C言語システムコール-mmap

mmapシステムコール

概要

mmapは指定ファイルをメモリ上にマップします。

ファイルをメモリにマップすると、メモリに対してアクセスすることでファイルにアクセスできるようになります。


mmapでマップしたメモリを解除する場合には「munmap」システムコールを利用します。

なお、mmapを実行したプロセスが終了すると、明示的にmunmapを呼び出さなくても、割り当てられたメモリは自動的に解放されます。

ただし、mmapでマップしたファイルをcloseしても解放はされません。


書き込みを行う場合には「msync」でバッファの更新を明示的に行う必要があります。

メモリのアクセス保護を変更するには「mprotect」を利用します。


サンプルプログラム

ファイル内容をメモリマップして、標準出力へ出力します。


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

/*!
 * @brief     ファイルサイズを取得する
 * @param[in] fd  ファイルディスクリプタ
 * @return    ファイルのサイズ
 * @return    -1:failure
 */
static int
get_filesize(int fd)
{
    int rc = 0;
    struct stat sb = {0};

    rc = fstat(fd, &sb);
    if(rc < 0){
        printf("Error: fstat() %s\n", strerror(errno));
        return(-1);
    }

    return(sb.st_size);
}

/*!
 * @brief     ファイル内容を出力する
 * @param[in] fd  ファイルディスクリプタ
 * @return    0:success/-1:failure
 */
static int
print_file_contents(int fd)
{
    int rc = 0;
    int fsize = 0;
    char *mp = NULL;

    /* ファイルサイズを取得する */
    fsize = get_filesize(fd);
    if(fsize < 0) return(-1);

    /* メモリに読み込み */
    mp = mmap(0, fsize, PROT_READ, MAP_PRIVATE, fd, 0);
    if(mp == MAP_FAILED){
        printf("Error: mmap() %s\n", strerror(errno));
        return(-1);
    }

    /* 出力する */
    fprintf(stdout, "%s\n", (char *)mp);

    /* メモリマップを解放する */
    rc = munmap(mp, fsize);
    if(rc < 0){
        printf("Error: munmap() %s\n", strerror(errno));
        return(-1);
    }

    return(0);
}

/*!
 * @brief     ファイル内容を出力する
 * @param[in] filepath  ファイルパス名
 * @return    0:success/-1:failure
 */
static int
print_file(char *filepath)
{
    int rc = 0;
    int fd = 0;

    fd = open(filepath, O_RDONLY);
    if(fd < 0){
        printf("Error: open() %s: %s\n", strerror(errno), filepath);
        return(-1);
    }

    rc = print_file_contents(fd);
    close(fd);

    return(rc);
}

int
main(int argc, char *argv[])
{
    int rc = 0;

    if(argc != 2){
        fprintf(stderr, "Usage: %s <path>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    rc = print_file(argv[1]);
    if(rc != 0) exit(EXIT_FAILURE);

    exit(EXIT_SUCCESS);
}


関連ページ