29 Haziran 2018 Cuma

mmap ile Memory Mapped File

Giriş
POSIX ile Memory Mapped File işlemi yapmak için temel iki metod mmap() ve munmap()'tir.

mmap metodu
1. Dosya açılır.
int myfd = open("hello.txt", O_RDWR);
2. Bu dosyanın büyüklüğünü alırız.
struct stat mystat = {};
fstat(myfd,&mystat);
3. Büyüklüğü bir değişkene aktarırız.
off_t myfsz = mystat.st_size;
4. Daha sonra dosyayı mmap ile Memory Mapped File haline getiririz.
void*ad = mmap(NULL, myfsz, PROT_READ|PROT_WRITE, MAP_SHARED,myfd, 0);
if (ad == MMAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); };
Eğer istenirse dosyanın belli bir kısmı belleğe alınabilir.
/* Map the first 1 MB of the file. */
pMap1 = (char *)mmap(0, 1024*1024, PROT_READ, MAP_SHARED, fd, 0);
Örnek
Tam bir örnek için şöyle yaparız.
int fd = open(filename, O_RDONLY); // open file
struct stat fs;
fstat(fd, &fs);

char *buf = (char*)mmap(0, fs.st_size, PROT_READ, MAP_SHARED, fd, 0));

char *buff_end = buf + fs.st_size;

munmap(buf, fs.st_size);

close(fd);
Örnek
Eğer dosya büyüklüğü ile mmap büyüklüğü farklı ise SIGBUS hatası alınır. Elimizde şöyle bir kod olsun. dosya açılırken truncate edildiği için hata alırız.
struct rgn_desc
{
  size_t end_;
  char data[];
};

int main(int argc, const char *argv[])
{
  int fd = open("foo.mm", O_RDWR|O_CREAT|O_TRUNC, (mode_t)0700);

  assert(fd != -1);

  void * ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
                    MAP_SHARED | MAP_POPULATE, fd, 0);

  assert(ptr != (void*) -1);

  rgn_desc * rgn_ptr = (rgn_desc*) ptr;
  rgn_ptr->end_ = 0; // <-- bus error
}

Hiç yorum yok:

Yorum Gönder