Maparea fisierelor este o forma de memory mapped I/O. O parte a unui fisier este mapata in cadrul memoriei; orice scriere a unei valori in memorie va fi resimtita in fisier si viceversa.
Exista trei apeluri folosite:
#include <sys/mman.h> void *mmap (void *start, size_t len, int prot, int flags, int fd, off_t offset); int munmap (void *start, size_t len); int msync (void *start, size_t len, int flags);
Apelul mmap este cel care se ocupa de maparea fisierului in memorie. start este adresa de memorie unde se cere mapat fisierul; la fel ca si la shmat se va preciza NULL (kernel-ul va face o alegere mult mai buna). len este dimensiunea zonei care se doreste mapata; prot este protectia asociata zonei mapate (PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE); fd este descriptorul fisierului care se doreste mapat, offset este deplasamentul fata de inceputul fisierului de unde se face maparea.
Campul flags poate avea valorile:
Apelul msync forteaza ca schimbarile efectuate asupra copiei din memorie sa fie scrise pe disc. In lipsa acestui apel, nu exista nici o garantie ca schimbarile vor fi scrise pana in momentul apelarii munmap.
Datorita proprietatilor device-ului /dev/zero se poate realiza o implementare a unei zone de memorie partajata intre procese tata/fiu. Mai jos este prezentat un program care exemplifica acest lucru:
/* * mmap.c: program ce demonstreaza utilizarea mmap pentru crearea unei * zone de memorie partajata */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/mman.h> int main (void) { int fd; pid_t pid; char *area; int status; fd = open ("/dev/zero", O_RDWR); if (fd < 0) { perror ("open"); exit (EXIT_FAILURE); } area = (char *) mmap (NULL, 20, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if ((void *) area == (void *) -1) { perror ("mmap"); exit (EXIT_FAILURE); } close (fd);/* dupa mapare putem inchide fisierul */ pid = fork (); switch (pid) { case -1: perror ("fork"); exit (EXIT_FAILURE); case 0: strncpy (area, "hello", 20); exit (EXIT_SUCCESS); } wait (&status); printf ("%s\n", area); munmap (area, 20); return 0; }
Un exemplu de rualre este:
razvan@ragnarok:~/cfiles/solab/labs/lab6$ gcc -Wall -pedantic -ansi mmap.c razvan@ragnarok:~/cfiles/solab/labs/lab6$ ./a.out hello razvan@ragnarok:~/cfiles/solab/labs/lab6$ ls