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);
}