A UNIX operációs rendszer újabb változatai lehetoséget adnak a fájlok memórián keresztül történo elérésére a fájlnak a memóriába ágyazásával (ezzel lehetoség nyílik a fájl tartalmának memóriamuveletek segítségével történo módosítására, amely gyakran hatékonyabb a hagyományos read() illetve write() rendszerhívásoknál.) Erre az mmap() UNIX rendszerhívást használhatjuk, melynek prototípusa a következo:
caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset);
Az mmap() rendszerhívás elso paramétere caddr_t
típusú (az ilyen típusú változók
egy tetszoleges memóriacímet kaphatnak értékül,
általában char *
típussal implementálják). Az elso
argumentumban azt a memóriacímet kell megadnunk, ahova be akarjuk ágyazni
a kérdéses fájlt (vagy annak egy részét). A programok
hordozhatósága érdekében itt 0-t adjunk meg, ugyanis ekkor az operációs
rendszer maga választ egy szabad memóriaterületet, ahova a fájlt
beágyazza. Sikeres végrehajtás esetén az mmap() rendszerhívás
az fd argumentumban kijelölt fájldeszkriptorú fájl
offset argumentumában adott pozíciótól kezdodo
len
argumentumban bájtokban megadott hosszú részét beágyazza, és
a rendszerhívás visszatérési értéke a beágyazott fájl-rész
memóriabeli kezdocíme (a beágyazás kezdocíme).
A prot paramétert a PROT_READ
, PROT_WRITE
,
PROT_EXEC
szimbólikus konstansok bitenkénti VAGY
muvelettel képzett kapcsolatával állíthatjuk elo aszerint,
hogy a beágyazott fájl-részen milyen muveleteket akarunk
megengedni (olvasni,írni vagy végrehajtani akarjuk a részeit). Ha egy
fájlra nincs írási engedélyünk a hozzá tárolt rwx-bitek
alapján, akkor a memóriába ágyazással sem módosíthatjuk azt.
A flags argumentum értéke vagy MAP_PRIVATE
vagy
pedig MAP_SHARED
lehet (általában). Ha itt
MAP_PRIVATE
-et adunk meg, akkor a fájlon végzett módosítások
idolegesek, azaz az eredeti fájlon nem jelennek meg, a fájl többi
felhasználója nem látja azokat.
#include <stdio.h> #include <sys/types.h> #include <sys/mman.h> #include <fcntl.h> main() { int fd; char *ra; fd=creat("cmmap1t",0666); write(fd,"alma",4); close(fd); fd=open("cmmap1t",O_RDWR); ra=mmap(0,4,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0); if (ra == (caddr_t)(-1)) perror("mmap sikertelen"); *(ra+2)='f'; munmap(ra,4); close(fd); }