프로그래밍/Unix System Programming

언제나휴일 2015. 4. 2. 14:29

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

addr: 매핑할 프로세스 주소, 0을 주면 알아서 매핑할 주소를 찾아줌

length: 매핑할 바이트 수

prot: 매핑한 메모리의 권한 (PROT_READ, PROT_WRITE)

flags: 공유 여부(MAP_PRIVATE, MAP_SHARED)

fd: 매핑할 파일 디스크립터(만약 메모리 매핑만 한다면 -1), 매핑 이후에 닫아도 문제 없음

offset: 매핑할 파일의 오프셋

return: 매핑한 주소


int munmap(void *addr,size_t size)

addr: 매핑 주소

size: 해제할 크기(페이지 단위)


예제 1. 입력 인자로 전달받은 파일의 내용을 매핑한 후 표준 출력으로 출력

(cat 명령어)

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc,char **argv)
{
    if(argc != 2)
    {
        printf("Usage %s [filename]\n",argv[0]);
        return 0;
    }
    int fd = 0;
    fd = open(argv[1],O_RDONLY);
    if(fd<0)
    {
        perror("failed open");
    }
    struct stat sbuf;
    fstat(fd,&sbuf);
    char *base = 0;
    base = mmap(0,sbuf.st_size, PROT_READ, MAP_PRIVATE,
fd,0);
    if(base == 0)
    {
        printf("failed mmap\n");
        return 0;
    }
    write(1,base,sbuf.st_size);
   
    return 0;
}



예제 2. 새로운 파일을 생성하여 크기를 fseek, fread로 파일 크기를 조절한 후에 매핑

그리고 매핑한 주소에 문자열을 복사

(프로그램 수행 후에 생성한 파일 내용을 확인할 것)

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
    if(argc != 2)
    {
        printf("Usage %s [filename]\n",argv[0]);
        return 0;
    }
    int fd = 0;
    fd = open(argv[1],O_RDWR|O_CREAT|O_SYNC,0666);
    if(fd<0)
    {
        perror("failed open");
    }
    lseek(fd,100,SEEK_SET);
    char a='a';
    write(fd,&a,1);
    struct stat sbuf;
    fstat(fd,&sbuf);
    char *base = 0;
    base = mmap(0,sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED,
fd,0);
    close(fd);
    if(base == 0)
    {
        printf("failed mmap\n");
        return 0;
    }
    strcpy(base,"hello");
    write(1,base,sbuf.st_size);
     munmap(base,sbuf.st_size);
   
   
   
    return 0;
}



예제 3. 메모리 매핑을 이용하여 회원 관리 프로그램을 작성한다고 가정했을 때의 예광탄 코드


#include <sys/mman.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
typedef struct _Element Element;
struct _Element
{
   char id[10];
   char pw[10];
   char name[100];
};
#define MAX_ELEMENT 1000
#define ELE_MAP_SIZE (sizeof(Element)*MAX_ELEMENT)
Element *base;
int usage;

int AddMember(const char *id,const char *pw, const char *name)
{
   Element *el = base +usage;
   strcpy(el->id,id);
   strcpy(el->pw,pw);
   strcpy(el->name,name);
   usage++;
}
   
int main(int argc,char **argv)
{
    if(argc != 2)
    {
        printf("Usage %s [filename]\n",argv[0]);
        return 0;
    }
    int fd = open(argv[1],O_RDWR|O_CREAT);
    if(fd<0)
    {
        perror("failed open");
    }
    lseek(fd,ELE_MAP_SIZE,SEEK_SET);
    char a='a';
    write(fd,&a,1);

    struct stat sbuf;
    fstat(fd,&sbuf);

    base = mmap(0,sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);

    AddMember("abc","111","hello");
    munmap(base,sbuf.st_size);

    return 0;
}