mmap(2) System Calls Manual mmap(2) NOM mmap, munmap - Etablir/supprimer une projection en memoire (map/unmap) des fichiers ou des peripheriques BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include void *mmap(void addr[.length], size_t length, int prot, int flags, int fd, off_t offset); int munmap(void addr[.length], size_t length); Consultez la section NOTES pour plus d'informations sur les exigences de la macro de test de fonctionnalite. DESCRIPTION mmap() cree une nouvelle projection dans l'espace d'adressage virtuel du processus appelant. L'adresse de demarrage de la nouvelle projection est indiquee dans addr. Le parametre length indique la longueur de la projection (qui doit etre superieure a 0). Si addr est NULL, le noyau choisit l'adresse (alignee sur une page) a laquelle demarrer la projection ; c'est la methode la plus portable pour creer une nouvelle projection. Si addr n'est pas NULL, le noyau le considere comme une indication sur l'endroit ou placer la projection ; sous Linux, elle sera placee a une frontiere de page proche (mais toujours superieure ou egale a la valeur indiquee par /proc/sys/vm/mmap_min_addr) et tente d'y creer la projection. Si une projection y existe deja, le noyau prend une nouvelle adresse qui peut ou pas dependre de l'indication. L'adresse de la nouvelle projection est renvoyee comme resultat de l'appel. Le contenu d'une projection de fichier (par opposition a une projection anonyme ; voir ci-dessous MAP_ANONYMOUS) est initialise avec length octets a partir de la position offset dans le fichier (ou autre objet) correspondant au descripteur de fichier fd. offset doit etre un multiple de la taille de la page renvoyee par sysconf(_SC_PAGE_SIZE). Apres le retour de l'appel mmap(), le descripteur de fichier fd peut etre ferme immediatement sans invalider la projection. L'argument prot indique la protection que l'on desire pour cette zone de memoire et ne doit pas entrer en conflit avec le mode d'ouverture du fichier. Il s'agit soit de PROT_NONE (le contenu de la memoire est inaccessible) soit d'un OU binaire entre les constantes suivantes : PROT_EXEC Il est possible d'executer les pages. PROT_READ Il est possible de lire les pages. PROT_WRITE Il est possible d'ecrire les pages. PROT_NONE Il n'est pas possible d'acceder aux pages. Le parametre des attributs Le parametre flags determine si les modifications de la projection sont visibles depuis les autres processus projetant la meme region et si les modifications sont appliquees au fichier sous-jacent. Ce comportement est determine en incluant exactement une des valeurs suivantes dans flags : MAP_SHARED Partager la projection. Les modifications de la projection sont visibles dans les autres processus qui projettent la meme region et (en cas de projection file-backed) elles sont appliquees au fichier sous-jacent (pour controler precisement le moment des mises a jour du fichier sous-jacent, il faut utiliser msync(2)). MAP_SHARED_VALIDATE (depuis Linux 4.15) Cet attribut apporte le meme comportement que MAP_SHARED sauf que les projections MAP_SHARED ignorent les attributs inconnus dans flags. Au contraire, lors de la creation d'une projection en utilisant MAP_SHARED_VALIDATE, le noyau verifie que tous les attributs passes sont connus et il fait echouer la projection avec l'erreur EOPNOTSUPP pour les attributs inconnus. Ce type de projection est aussi necessaire pour pouvoir utiliser certains attributs de projection (comme MAP_SYNC). MAP_PRIVATE Creer une projection privee, utilisant la methode de copie a l'ecriture. Les modifications de la projection ne sont pas visibles depuis les autres processus projetant le meme fichier, et ne modifient pas le fichier lui-meme. Il n'est pas precise si les changements effectues dans le fichier apres l'appel mmap() seront visibles dans la region projetee. MAP_SHARED et MAP_PRIVATE sont decrits dans POSIX.1-2001 et POSIX.1-2008. MAP_SHARED_VALIDATE est une extension Linux. De plus, zero ou plus des valeurs suivantes peuvent etre incluses dans flags (avec un OU binaire) : MAP_32BIT (depuis Linux 2.4.20, 2.6) Placer la projection dans les deux premiers gigaoctets de l'espace d'adressage du processus. Cet attribut n'est pris en charge que sous x86-64, pour les programmes 64 bits. Il a ete ajoute pour permettre a la pile d'un fil d'execution d'etre allouee dans les deux premiers gigaoctets de memoire, afin d'ameliorer les performances des changements de contexte sur les premiers processeurs 64 bits. Les processeurs x86-64 modernes n'ont plus ces problemes de performance, donc l'utilisation de cet attribut n'est pas necessaire sur ces systemes. L'attribut MAP_32BIT est ignore quand MAP_FIXED est positionne. MAP_ANON Synonyme de MAP_ANONYMOUS ; fourni pour une compatibilite avec d'autres implementations. MAP_ANONYMOUS La projection n'est prise en charge par aucun fichier ; son contenu est initialise a 0. L'argument fd est ignore ; cependant, certaines implementations demandent que fd soit -1 si MAP_ANONYMOUS (ou MAP_ANON) est utilise, et les applications portables doivent donc s'en assurer. L'argument offset devrait etre 0. La prise en charge de MAP_ANONYMOUS avec MAP_SHARED a ete ajoutee dans Linux 2.4. MAP_DENYWRITE Cet attribut est ignore (autrefois -- Linux 2.0 et anterieur -- il signalait une tentative d'ecriture dans le fichier sous-jacent et qui echouait avec l'erreur ETXTBUSY. Mais cela permettait des attaques par deni de service). MAP_EXECUTABLE Cet attribut est ignore. MAP_FILE Attribut pour compatibilite. Ignore. MAP_FIXED Ne pas considerer addr comme une indication : n'utiliser que l'adresse indiquee. addr doit etre correctement alignee : pour la plupart des architectures, un multiple de la taille de page suffit, toutefois certaines architectures imposent des limitations supplementaires. Si la zone memoire indiquee par addr et length recouvre des pages d'une projection existante, la partie recouverte de la projection existante sera ignoree. Si l'adresse indiquee ne peut etre utilisee, mmap() echouera. Les logiciels qui aspirent a la portabilite devraient utiliser l'attribut MAP_FIXED prudemment, en gardant a l'esprit que l'aspect exact des projections de memoire du processus est autorise a changer significativement entre les versions de Linux, de la glibc et du systeme d'exploitation. Lisez attentivement le point sur cet attribut dans les NOTES ! MAP_FIXED_NOREPLACE (depuis Linux 4.17) Cet attribut offre un comportement identique a MAP_FIXED par rapport a l'application de addr, mais il s'en distingue en ce que MAP_FIXED_NOREPLACE n'ecrase jamais une plage projetee existante. Si la plage demandee entre en conflit avec une projection existante, cet appel echoue avec l'erreur EEXIST. Cet attribut peut donc etre utilise comme une facon d'essayer de projeter une plage d'adresses de maniere atomique (vis-a-vis d'autres fils d'executions) : un thread reussira, tous les autres signaleront un echec. Remarquez que les anciens noyaux qui ne reconnaissent pas l'attribut MAP_FIXED_NOREPLACE se rabattront generalement (en detectant une collision avec une projection existante) sur un type de comportement << sans MAP_FIXED >> : ils renverront une adresse differente de celle demandee. Les logiciels retro-compatibles devront donc verifier l'adresse renvoyee vis-a-vis de l'adresse demandee. MAP_GROWSDOWN Cet attribut est utilise pour les piles. Il indique au noyau le systeme de memoire virtuelle vers lequel la projection devrait descendre dans la memoire. L'adresse renvoyee est une page inferieure a la zone de memoire creee dans l'espace d'adressage virtuel du processus. La modification d'une adresse dans la page de << garde >> sous la projection fera agrandir la projection d'une page. Cette croissance peut se repeter jusqu'a ce que la taille de la projection dans la page atteigne l'extremite haute de la projection plus basse suivante, point ou la modification de la page de << garde >> donnera un signal SIGSEGV. MAP_HUGETLB (depuis Linux 2.6.32) Allouer la projection a l'aide de << pages immenses >>. Consultez le fichier Documentation/vm/hugetlbpage.txt des sources du noyau Linux pour plus d'informations ainsi que les NOTES ci-dessous. MAP_HUGE_2MB MAP_HUGE_1GB (depuis Linux 3.8) Utilise avec MAP_HUGETLB pour selectionner d'autres tailles de pages immenses (hugetlb) (respectivement 2 Mo et 1 Go) sur les systemes qui gerent plusieurs tailles de page hugetlb. Plus generalement, la taille de la page immense souhaitee peut etre configuree en encodant le logarithme de base 2 de la taille de la page desiree dans les six bits situes sur MAP_HUGE_SHIFT (une valeur de zero dans ce champ de bit fournit la taille de page immense par defaut ; vous pouvez connaitre celle-ci a l'aide du champ Hugepagesize qui apparait dans /proc/meminfo). Ainsi, les deux constantes ci-dessus sont definies comme suit : #define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) #define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) Vous pouvez connaitre l'intervalle de tailles des pages immenses gerees par le systeme en listant les sous-repertoires de /sys/kernel/mm/hugepages. MAP_LOCKED (depuis Linux 2.5.37) Marquer la region projetee pour qu'elle soit verrouillee de la meme maniere que mlock(2). Cette implementation essaiera de remplir (prefault) toute la plage mais l'appel mmap() n'echouera pas avec ENOMEM si cela echoue. Des erreurs enormes pourraient donc se produire ulterieurement. La semantique n'est donc pas aussi robuste que mlock(2). Vous devriez utiliser mmap() et mlock(2) si d'enormes erreurs ne sont pas acceptables apres l'initialisation de la projection. L'attribut MAP_LOCKED est ignore sur les anciens noyaux. MAP_NONBLOCK (depuis Linux 2.5.46) Cet attribut n'a de sens qu'en conjonction avec MAP_POPULATE. Ne pas effectuer de lecture anticipee : creer seulement les entrees de tables de page pour les pages deja presentes en RAM. Depuis Linux 2.6.23, cet attribut fait que MAP_POPULATE n'a aucun effet. Un jour la combinaison de MAP_POPULATE et MAP_NONBLOCK pourra etre implementee de nouveau. MAP_NORESERVE Ne pas reserver d'espace de swap pour les pages de cette projection. Une telle reservation garantit que l'on puisse modifier les zones soumises a une copie-en-ecriture. Sans reservation, on peut recevoir un signal SIGSEGV durant une ecriture, s'il n'y a plus de place disponible. Consultez egalement la description du fichier /proc/sys/vm/overcommit_memory dans la page proc(5). Avant Linux 2.6, cet attribut n'avait d'effet que pour les projections privees modifiables. MAP_POPULATE (depuis Linux 2.5.46) Remplir (prefault) les tables de pages pour une projection. Pour une projection de fichier, cela provoque une lecture anticipee du fichier. Les acces ulterieurs a la projection ne seront pas bloques par des erreurs de pages. L'appel mmap n'echoue pas si la projection ne peut pas etre remplie (par exemple a cause de limitation sur le nombre de pages immenses mappees lors de l'utilisation de MAP_HUGETLB). La prise en charge de MAP_POPULATE avec les projections privees a ete ajoutee dans Linux 2.6.23. MAP_STACK (depuis Linux 2.6.27) Allouer la projection a une adresse qui convient a la pile d'un processus ou d'un thread. Cet attribut n'est pas operationnel pour l'instant sur Linux. Mais son utilisation permet aux applications de s'assurer qu'elles le gereront de maniere transparente s'il est implemente dans le futur. Ainsi, il est utilise dans l'implementation de threading de la glibc pour accepter le fait que certaines architectures pourront (plus tard) necessiter un traitement special pour allouer des piles. Une autre raison d'utiliser cet attribut est la portabilite : MAP_STACK existe et a un effet sur d'autres systemes (comme certains BSD). MAP_SYNC (depuis Linux 4.15) Cet attribut n'est possible qu'avec le type de projection MAP_SHARED_VALIDATE ; les projections de type MAP_SHARED ignoreront silencieusement cet attribut. Il n'est pris en charge que pour des fichiers gerant le DAX (projection directe de memoire persistante). Pour les autres fichiers, creer une projection avec cet attribut provoquera une erreur EOPNOTSUPP. Les projections de fichier partage ayant cet attribut fournissent une garantie que tant que la memoire est projetee avec acces en ecriture dans l'espace d'adressage du processus, elle sera visible dans le meme fichier et au meme endroit meme apres un plantage ou un redemarrage du systeme. Couple a l'utilisation des instructions adequates du processeur, cela offre aux utilisateurs de telles projections une maniere plus efficace de rendre des modifications de donnees persistantes. MAP_UNINITIALIZED (depuis Linux 2.6.33) Ne pas effacer pas les pages anonymes. Cet attribut n'a pour l'instant un effet que si le noyau a ete configure avec l'option CONFIG_MMAP_ALLOW_UNINITIALIZED. A cause des implications sur la securite, cette option n'est normalement active que sur des peripheriques embarques (c'est-a-dire avec des peripheriques avec lesquels il est possible d'avoir un controle total de la memoire utilisateur). Parmi les attributs ci-dessus, seul MAP_FIXED est specifie dans POSIX.1-2001 et POSIX.1-2008. Cependant, la plupart des systemes gerent aussi MAP_ANONYMOUS (ou son synonyme MAP_ANON). munmap() L'appel systeme munmap() detruit la projection dans la zone de memoire specifiee et s'arrange pour que toute reference ulterieure a cette zone memoire declenche une erreur d'adressage. La projection est aussi automatiquement detruite lorsque le processus se termine. A l'inverse, la fermeture du descripteur de fichier ne supprime pas la projection. L'adresse addr doit etre un multiple de la taille de la page (mais ce n'est pas obligatoire pour length). Toutes les pages contenant une partie de l'intervalle indique sont liberees, et tout acces ulterieur declenchera SIGSEGV. Aucune erreur n'est detectee si l'intervalle indique ne contient pas de page projetee. VALEUR RENVOYEE En cas de succes, mmap() renvoie un pointeur sur la zone projetee. En cas d'echec, la valeur MAP_FAILED (c'est-a-dire (void *) -1) est renvoyee et errno est defini pour indiquer l'erreur. S'il reussit, munmap() renvoie 0. En cas d'echec, -1 est renvoye et errno est defini pour indiquer l'erreur (probablement EINVAL). ERREURS EACCES Le descripteur ne correspond pas a un fichier normal ou une demande de projection de fichier a ete demandee mais fd n'est pas ouvert en lecture, ou une demande de projection partagee MAP_SHARED avec protection PROT_WRITE a ete demandee mais fd n'est pas ouvert en lecture et ecriture (O_RDWR), ou encore PROT_WRITE est demande mais le fichier est ouvert en ajout seulement. EAGAIN Le fichier est verrouille ou trop de pages ont ete verrouillees en memoire (consultez setrlimit(2)). EBADF fd n'est pas un descripteur de fichier valable (et MAP_ANONYMOUS n'etait pas precise). EEXIST MAP_FIXED_NOREPLACE etait indique dans flags et la plage couverte par addr et length est en conflit avec une projection existante. EINVAL addr ou length ou offset sont non valables (par exemple : zone trop grande, ou non alignee sur une frontiere de page). EINVAL (depuis Linux 2.6.12) length est nul. EINVAL flags ne contenait ni MAP_PRIVATE, ni MAP_SHARED, ni MAP_SHARED_VALIDATE. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENODEV Le systeme de fichiers sous-jacent ne gere pas la projection en memoire. ENOMEM Aucune memoire disponible. ENOMEM Le nombre maximal de projections du processus serait depasse. Cette erreur peut aussi se produire pour munmap() lors de la suppression d'une projection d'une region au milieu d'une projection existante, puisque cela provoque deux regions plus petites de chaque cote de la region a supprimer. ENOMEM (Depuis Linux 4.7) La limite RLIMIT_DATA du processus, decrite dans getrlimit(2), serait depassee. ENOMEM addr n'est pas apprecie parce qu'il depasse l'espace d'adressage virtuel du processeur EOVERFLOW Sur architecture 32 bits avec l'extension de fichiers tres grands (c'est-a-dire utilisant un off_t sur 64 bits) : le nombre de pages utilisees pour length plus le nombre de pages utilisees pour offset depasserait unsigned long (32 bits). EPERM L'argument prot a demande PROT_EXEC mais la zone appartient a un fichier sur un systeme de fichiers monte sans permission d'execution. EPERM La lecture a ete interrompue par un signal ; consultez fnctl(2). EPERM L'attribut MAP_HUGETLB etait indique, mais l'appelant n'etait pas priviliegie (il n'avait pas la capacite CAP_IPC_LOCK) et n'est pas membre du groupe sysctl_hugetlb_shm_group ; voir la desription de /proc/sys/vm/sysctl_hugetlb_shm_group dans proc_sys(5). ETXTBSY MAP_DENYWRITE a ete reclame mais fd est ouvert en ecriture. L'acces a une zone de projection peut declencher les signaux suivants : SIGSEGV Tentative d'ecriture dans une zone en lecture seule. SIGBUS Tentative d'acces a une page du tampon au-dela de la fin du fichier projete. Pour une explication du traitement des octets dans la page correspondant a la fin du fichier projete n'etant pas un multiple de la taille de la page, voir les NOTES. ATTRIBUTS Pour une explication des termes utilises dans cette section, consulter attributes(7). +---------------------------------+--------------------------+---------+ |Interface | Attribut | Valeur | +---------------------------------+--------------------------+---------+ |mmap(), munmap() | Securite des threads | MT-Safe | +---------------------------------+--------------------------+---------+ VERSIONS Sur certaines architectures materielles (par exemple, i386), PROT_WRITE implique PROT_READ. Cela depend de l'architecture si PROT_READ implique PROT_EXEC ou non. Les programmes portables doivent toujours indiquer PROT_EXEC s'ils veulent executer du code dans la projection. La maniere portable de creer une projection est de specifier addr a 0 (NULL), et d'omettre MAP_FIXED dans flags. Dans ce cas, le systeme choisit l'adresse de la projection ; l'adresse est choisie de maniere a ne pas entrer en conflit avec une projection existante et de ne pas etre nulle. Si l'attribut MAP_FIXED est indique et si addr vaut 0 (NULL), l'adresse projetee sera zero (NULL). Certaines constantes de flags sont definies seulement si des macros de test de fonctionnalites adaptees sont definies (potentiellement par defaut) : _DEFAULT_SOURCE avec la glibc 2.19 ou superieure, ou bien _BSD_SOURCE ou _SVID_SOURCE dans la glibc 2.19 et anterieure (la definition de _GNU_SOURCE suffit egalement, et son usage aurait ete plus logique, puisque ces attributs sont tous specifiques a Linux). Les attributs adequats sont : MAP_32BIT, MAP_ANONYMOUS (et son synonyme MAP_ANON), MAP_DENYWRITE, MAP_EXECUTABLE, MAP_FILE, MAP_GROWSDOWN, MAP_HUGETLB, MAP_LOCKED, MAP_NONBLOCK, MAP_NORESERVE, MAP_POPULATE, et MAP_STACK. Differences entre bibliotheque C et noyau Cette page decrit l'interface fournie par la fonction mmap() de la glibc. Initialement, cette fonction appelait un appel systeme du meme nom. Depuis Linux 2.4, cet appel systeme a ete remplace par mmap2(2). De nos jours, la fonction mmap() de la glibc appelle mmap2(2) avec la bonne valeur pour offset. STANDARDS POSIX.1-2008. HISTORIQUE POSIX.1-2001, SVr4, 4.4BSD. Sur les systemes POSIX sur lesquels mmap(), msync(2) et munmap() sont disponibles, _POSIX_MAPPED_FILES est definie dans comme etant une valeur superieure a 0 (consultez aussi sysconf(3)). NOTES La memoire obtenue par mmap est preservee au travers d'un fork(2), avec les memes attributs. Un fichier est projete en multiples de de la taille de la page. Pour un fichier dont la longueur n'est pas un multiple de la taille de page, la memoire restante est remplie de zeros lors de la projection, et les ecritures dans cette zone n'affectent pas le fichier. Les effets de la modification de la taille du fichier sous-jacent sur les pages correspondant aux zones ajoutees ou supprimees ne sont pas precises. Une application peut determiner les pages d'une projection se trouvant dans le tampon/le cache de page en utilisant mincore(2). Utilisation sure de MAP_FIXED La seule utilisation sure de MAP_FIXED est quand la plage d'adresses indiquee par addr et length a ete prealablement reservee en utilisant une autre projection ; sans quoi l'utilisation de MAP_FIXED est hasardeuse car elle supprime brutalement des projections preexistantes, ce qui facilite la corruption par un processus multithread de son propre espace d'adressage. Par exemple, supposons qu'un thread A cherche dans /proc/pid/maps une plage d'adresses inutilisee ou il peut se projeter en utilisant MAP_FIXED, tandis qu'un thread B acquiert en meme temps tout ou partie de cette meme plage d'adresses. Quand le thread A utilisera ensuite mmap(MAP_FIXED), il va de fait ecraser la projection creee par le thread B. Dans ce scenario, le thread B ne doit pas creer de projection directement ; un appel de bibliotheque qui, en interne, utilise dlopen(3) pour charger d'autres bibliotheques partagees, est suffisant. L'appel dlopen(3) projettera la bibliotheque dans l'espace d'adressage du processus. De plus, presque tous les appels de bibliotheques peuvent etre implementes d'une maniere qui ajoute des projections de memoire aux espaces d'adressage, a l'aide de cette technique ou en allouant simplement de la memoire. Parmi les exemples, figurent brk(2), malloc(3), pthread_create(3) et les bibliotheques PAM . Depuis Linux 4.17, un programme multithreade peut utiliser l'attribut MAP_FIXED_NOREPLACE pour eviter le risque decrit ci-dessus quand on essaie de creer une projection a une adresse fixe non reservee par une projection preexistante. Modifications d'horodatage pour les projections prises en charge par un fichier Pour les projections prises en charge par un fichier, le champ st_atime du fichier peut etre mis a jour a tout moment entre l'appel mmap() et le munmap() correspondant. Le premier acces dans la page projetee mettra le champ a jour si cela n'a pas ete deja fait. Les champs st_ctime et st_mtime pour un fichier projete avec PROT_WRITE et MAP_SHARED seront mis a jour apres une ecriture dans la region projetee, et avant l'eventuel msync(2) suivant avec l'attribut MS_SYNC ou MS_ASYNC. Projections de pages immenses (Huge TLB) Pour les projections qui utilisent des pages immenses, les exigences des attributs de mmap() et de munmap() different quelque peu de celles pour des projections qui utilisent la taille native des pages du systeme. Pour mmap(), offset doit etre un multiple de la taille de la page immense sous-jacente. Le systeme aligne automatiquement length pour qu'il soit un multiple de la taille de la page immense sous-jacente. Pour munmap(), addr et length doivent etre tous deux un multiple de la taille de la page immense sous-jacente. BOGUES Sous Linux, il n'y a aucune garantie comme celles indiquees plus haut a propos de MAP_NORESERVE. Par defaut, n'importe quel processus peut etre tue a tout moment lorsque le systeme n'a plus de memoire. Avant Linux 2.6.7, l'attribut MAP_POPULATE n'avait d'effet que si prot etait PROT_NONE. SUSv3 indique que mmap() devrait echouer si length est 0. Cependant, avant Linux 2.6.12, mmap() reussissait dans ce cas : aucune projection n'etait creee, et l'appel renvoyait addr. Depuis Linux 2.6.12, mmap() echoue avec le code d'erreur EINVAL si length est nul. POSIX specifie que le systeme devrait toujours remplir de zeros toutes les pages incompletes a la fin de l'objet et que le systeme n'ecrira jamais de modification de l'objet au-dela de sa fin. Sous Linux, lors de l'ecriture de donnees vers ce genre de pages incompletes apres la fin de l'objet, les donnees restent dans le cache de page meme apres que le fichier soit ferme et deprojete, et meme si les donnees ne sont jamais ecrites vers le fichier lui-meme, les projections suivantes pourraient voir le contenu modifie. Dans certains cas, cela pourrait etre corrige en appelant msync(2) avant la deprojection. Cependant, cela ne fonctionne pas sur tmpfs(5) (par exemple en utilisant l'interface de memoire partagee POSIX documentee dans shm_overview(7)). EXEMPLES Le programme suivant affiche la partie du fichier, precise par le premier argument de la ligne de commande, sur la sortie standard. Les octets qui seront affiches sont precises a partir d'un offset (deplacement) et d'une longueur en deuxieme et troisieme parametre. Le code fait une projection memoire des pages necessaires du fichier puis utilise write(2) pour afficher les octets voulus. Source du programme #include #include #include #include #include #include #include #define handle_error(msg) \e do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { int fd; char *addr; off_t offset, pa_offset; size_t length; ssize_t s; struct stat sb; if (argc < 3 || argc > 4) { fprintf(stderr, "%s position du fichier [longueur]\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDONLY); if (fd == -1) handle_error("open"); if (fstat(fd, &sb) == -1) /* To obtain file size */0 handle_error("fstat"); offset = atoi(argv[2]); pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1); /* la position de mmap() doit etre alignee sur la page */ if (offset >= sb.st_size) { fprintf(stderr, exit(EXIT_FAILURE); } if (argc == 4) { length = atoi(argv[3]); if (offset + length > sb.st_size) length = sb.st_size - offset; /* Ne peut pas afficher d'octets situes apres la fin du fichier */ } else { /* Pas d'affichage de longueur arg ==> a la fin du fichier */ length = sb.st_size - offset; } addr = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_PRIVATE, fd, pa_offset); if (addr == MAP_FAILED) handle_error( s = write(STDOUT_FILENO, addr + offset - pa_offset, length); if (s != length) { if (s == -1) handle_error("write"); fprintf(stderr, "ecriture partielle"); exit(EXIT_FAILURE); } munmap(addr, length + offset - pa_offset); close(fd); exit(EXIT_SUCCESS); } VOIR AUSSI ftruncate(2), getpagesize(2), memfd_create(2), mincore(2), mlock(2), mmap2(2), mprotect(2), mremap(2), msync(2), remap_file_pages(2), setrlimit(2), shmat(2), userfaultfd(2), shm_open(3), shm_overview(7) Dans proc(5), les descriptions des fichiers : /proc/pid/maps, /proc/pid/map_files et /proc/pid/smaps. B.O. Gallmeister, POSIX.4, O'Reilly, p. 128-129 et 389-391. TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.8 2 mai 2024 mmap(2)