Linux API/linux
mmap() 과 munmap() 예제
구차니
2023. 11. 17. 16:54
munmap은 주소와 길이만 있으면 되는데
mmap은 fd가 있어야 한다.
#include <sys/mman.h> void *mmap(void *addr, size_t lengthint " prot ", int " flags , int fd, off_t offset); int munmap(void *addr, size_t length); |
[링크 : https://linux.die.net/man/2/mmap]
그래서 직접 구현하려니 먼가 복잡하고 귀찮아서 찾아보니 실행되는 녀석 발견.
테스트 소스를 긁어와서 빌드하고 실행하면 되는데, 아래와 같이 두개의 인자를 주어야 한다.
일종의 cp 명령을 코드로 짠 느낌.
$ ./a.out in_filename out_filename
#include <stdio.h> #include <sys/mman.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <errno.h> int main(int argc, char *argv[]){ int srcfd, dstfd; //src 파일 서술자, dst 파일 서술자 void *src, *dst; //src 메모리 주소, dst 메모리 주소 size_t copysz; //다음 copy할 메모리 내용 size struct stat sbuf; off_t fsz = 0; //다음 읽기, 쓰기를 기록할 위치(offset) long page_size; //시스템의 PAGE SIZE if((srcfd = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "can't open %s for reading \n",argv[1]); exit(1); } if((dstfd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0777)) < 0){ fprintf(stderr, "can't open %s for writing\n", argv[2]); exit(1); } //file 사이즈 얻기 위한 용도 if(fstat(srcfd, &sbuf) < 0){ fprintf(stderr, "fstat error\n"); exit(1); } if(ftruncate(dstfd, sbuf.st_size) < 0){ fprintf(stderr, "ftruncate error\n"); exit(1); } page_size = sysconf(_SC_PAGESIZE); printf("page_size : %ld\n", page_size); while(fsz < sbuf.st_size){ if((sbuf.st_size - fsz ) > page_size) copysz = page_size; else copysz = sbuf.st_size - fsz; //src 주소 설정 if((src = mmap(0, copysz, PROT_READ, MAP_SHARED, srcfd, fsz)) == MAP_FAILED){ fprintf(stderr, "mmap error for input \n"); printf("error : %s\n",strerror(errno)); exit(1); } //dst 주소 설정 , 여기서 MAP_SHARED를 MAP_RPIVATE로 바꾸면? dst파일에 저장되지 않는다. if((dst = mmap(0, copysz, PROT_READ|PROT_WRITE, MAP_SHARED, dstfd, fsz)) == MAP_FAILED){ fprintf(stderr, "mmap error for output\n"); exit(1); } //src -> dst로 내용 복사 memcpy(dst, src, copysz); //메모리 해제 munmap(src, copysz); munmap(dst, copysz); //복사한 내용만큼 다음 메모리 위치를 이동시킬 offset 증가 fsz += copysz; } exit(0); } |
[링크 : https://reakwon.tistory.com/225]
특이한건 munmap() 에서 copysz를 /2로 해서 넣어도 return 값이 0 으로 나온다.
int ret = munmap(src, copysz / 2); printf("ret[%d]\n",ret); ret = munmap(dst, copysz / 2); printf("ret[%d]\n",ret); |
그러면.. 예상한것과 좀 다른데..
나중에 프로그램을 천천히 실행하도록 해서 메모리 누수가 발생하는지 찾아봐야 할 듯..