shm_open(3) Library Functions Manual shm_open(3) NOM shm_open, shm_unlink - Creer, ouvrir ou supprimer des objets en memoire partagee POSIX BIBLIOTHEQUE Bibliotheque de temps reel (librt, -lrt) SYNOPSIS #include #include /* Pour les constantes de mode */ #include /* Pour les constantes O_* */ int shm_open(const char *nom, int masque, mode_t mode); int shm_unlink(const char *nom); DESCRIPTION La fonction shm_open() cree et ouvre un nouvel objet en memoire partagee POSIX, ou ouvre un objet existant. Il s'agit d'un descripteur utilisable par des processus independants pour projeter la meme region memoire a l'aide de mmap(2). La fonction shm_unlink() realise l'operation inverse en supprimant l'objet cree precedemment par shm_open(). Le fonctionnement de shm_open() est analogue a celui de open(2). nom indique l'objet en memoire partagee a creer ou ouvrir. Pour un fonctionnement portable, un objet en memoire partagee doit etre identifie par un nom au format /un_nom ; c'est-a-dire une chaine terminee par un octet de valeur zero d'au plus NAME_MAX (c'est-a-dire 255) caracteres, et commencant par une barre oblique (<< / >>) suivie d'un caractere ou plus, ces derniers n'etant pas des barres obliques. masque est un masque de bits associant a l'aide d'un OU logique une et une seule des deux constantes O_RDONLY ou O_RDWR et un ou plusieurs des attributs decrits ci-apres : O_RDONLY Ouvrir l'objet en lecture seule. Un tel objet ne pourra etre projete en memoire avec mmap(2) qu'avec un acces en lecture (PROT_READ). O_RDWR Ouvrir l'objet en lecture et ecriture. O_CREAT Creer l'objet en memoire partagee s'il n'existe pas. L'utilisateur et le groupe proprietaires de l'objet proviennent des ID effectifs du processus appelant, et les bits de permission sont definis en fonction des 9 bits de poids faible de mode, excepte que les bits qui sont definis dans le masque de mode de fichier pour la creation du processus (consultez umask(2)) sont effaces pour le nouvel objet. Un jeu de constantes de macroutilisables pour definir le mode est decrit dans open(2) (les definitions symboliques de ces constantes peuvent etre obtenues en incluant ). Un nouvel objet en memoire partagee a une taille initiale nulle -- elle peut etre definie avec ftruncate(2). Les octets d'un objet en memoire partagee nouvellement cree sont automatiquement initialises a zero. O_EXCL Si O_CREAT etait aussi precise et si un objet en memoire partagee avec le meme nom existait deja, renvoyer une erreur. La verification de l'existence de l'objet et sa creation s'il n'existe pas sont realisees de maniere atomique. O_TRUNC Si l'objet en memoire partagee existe deja, tronquer sa taille a zero. Les definitions des valeurs de ces attributs peuvent etre obtenues en incluant . Si elle reussit, la fonction shm_open() renvoie un nouveau descripteur de fichierreferencant l'objet en memoire partagee. Ce descripteur sera le plus petit numero disponible dans la table des descripteurs du processus. L'attribut FD_CLOEXEC (consultez fcntl(2)) sera active pour le descripteur de fichier. Le descripteur de fichier est utilise normalement pour les appels ulterieurs a ftruncate(2) (pour un objet nouvellement cree) et mmap(2). Apres un appel a mmap(2) le descripteur peut etre ferme sans affecter la projection memoire. Le fonctionnement de shm_unlink() est analogue a celui de unlink(2) : il supprime le nom d'un objet en memoire partagee, et, une fois que tous les processus ont supprime leur projection en memoire, libere et detruit le contenu de la portion de memoire associee. Apres un appel reussi a shm_unlink(), les tentatives d'appeler shm_open() avec le meme nom echoueront (sauf si O_CREAT est specifie, auquel cas un nouvel objet distinct sera cree). VALEUR RENVOYEE Si elles reussissent, shm_open() renvoie un descripteur de fichier (un entier non negatif) et shm_unlink() renvoie 0. En cas d'echec, les deux fonctions renvoient -1 et definissent errno pour indiquer l'erreur. ERREURS EACCES La permission d'utiliser shm_unlink() sur l'objet en memoire partagee a ete refusee. EACCES L'utilisation de shm_open() pour ouvrir l'objet nom dans le mode specifie a ete refusee, ou O_TRUNC a ete specifie et l'appelant n'a pas les permissions d'ecriture sur l'objet. EEXIST O_CREAT et O_EXCL ont ete specifies dans shm_open() et un objet de memoire partagee du meme nom existe deja. EINVAL L'argument nom de shm_open() n'etait pas valable. EMFILE La limite du nombre de descripteurs de fichiers par processus a ete atteinte. ENAMETOOLONG La longueur du nom depasse PATH_MAX. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENOENT Tentative d'ouvrir avec shm_open() un objet nom qui n'existe pas, alors que l'attribut O_CREAT n'a pas ete specifie. ENOENT Tentative d'utiliser shm_unlink() sur un objet nom qui n'existe pas. ATTRIBUTS Pour une explication des termes utilises dans cette section, consulter attributes(7). +--------------------------+--------------------------+----------------+ |Interface | Attribut | Valeur | +--------------------------+--------------------------+----------------+ |shm_open(), shm_unlink() | Securite des threads | MT-Safe locale | +--------------------------+--------------------------+----------------+ VERSIONS POSIX ne precise pas le comportement de la combinaison O_RDONLY et O_TRUNC. Sous Linux, la troncature aura lieu -- cela n'est pas necessairement le cas sous d'autres systemes UNIX. L'implementation sous Linux des objets de memoire partagee POSIX utilise un systeme de fichiers tmpfs(5) dedie, monte en principe sous /dev/shm. STANDARDS POSIX.1-2008. HISTORIQUE glibc 2.2. POSIX.1-2001. POSIX.1-2001 indique que le groupe proprietaire d'un objet en memoire partagee nouvellement cree utilise soit l'ID de groupe du processus appelant, soit un << ID de groupe par defaut defini par le systeme >>. POSIX.1-2008 indique que le groupe proprietaire peut etre defini soit avec l'ID de groupe du processus appelant, soit, si l'objet est visible dans le systeme de fichiers, avec l'ID de groupe du repertoire parent. EXEMPLES Les programmes ci-dessous utilisent la memoire partagee POSIX et des semaphores non nommes POSIX pour echanger des donnees. Le programme << bounce >> (qui doit etre execute en premier) illustre le cas d'une chaine placee en memoire partagee par le programme << send >>. Lorsque les donnees ont ete modifiees, le programme << send >> affiche le contenu de la memoire partagee modifie. Voici un exemple d'execution des deux programmes : $ ./pshm_ucase_bounce /myshm & [1] 270171 $ ./pshm_ucase_send /myshm bonjour BONJOUR Vous trouverez plus de details a propos de ces programmes ci-dessous. Source du programme : pshm_ucase.h Ce fichier d'en-tete est inclus par les deux programmes ci-dessous. Sa principale fonction consiste a definir une structure qui sera imposee a l'objet en memoire partage entre les deux programmes. #include #include #include #include #include #include #include #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0) #define BUF_SIZE 1024 /* Maximum size for exchanged string */ /* Define a structure that will be imposed on the shared memory object */ struct shmbuf { sem_t sem1; /* POSIX unnamed semaphore */ sem_t sem2; /* POSIX unnamed semaphore */ size_t cnt; /* Number of bytes used in 'buf' */ char buf[BUF_SIZE]; /* Data being transferred */ }; Source programme : pshm_ucase_bounce.c Le programme << bounce >> cree un nouvel objet en memoire partagee avec le nom specifie comme argument de la ligne de commande et le dimensionne de maniere a correspondre a la taille de la structure shmbuf definie dans le fichier d'en-tete. Il projette ensuite l'objet dans l'espace d'adressage du processus et initialise deux semaphores POSIX a 0 a l'interieur de l'objet. Une fois le premier semaphore poste par le programme << send >>, le programme << bounce >> met en capitales les donnees placees en memoire par le programme << send >>, puis poste le second semaphore pour indiquer au programme << send >> qu'il peut maintenant acceder a la memoire partagee. /* pshm_ucase_bounce.c Licensed under GNU General Public License v2 or later. */ #include #include "pshm_ucase.h" int main(int argc, char *argv[]) { int fd; char *shmpath; struct shmbuf *shmp; if (argc != 2) { fprintf(stderr, "Usage: %s /shm-path\n", argv[0]); exit(EXIT_FAILURE); } shmpath = argv[1]; /* Create shared memory object and set its size to the size of our structure. */ fd = shm_open(shmpath, O_CREAT | O_EXCL | O_RDWR, 0600); if (fd == -1) errExit("shm_open"); if (ftruncate(fd, sizeof(struct shmbuf)) == -1) errExit("ftruncate"); /* Map the object into the caller's address space. */ shmp = mmap(NULL, sizeof(*shmp), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (shmp == MAP_FAILED) errExit("mmap"); /* Initialize semaphores as process-shared, with value 0. */ if (sem_init(&shmp->sem1, 1, 0) == -1) errExit("sem_init-sem1"); if (sem_init(&shmp->sem2, 1, 0) == -1) errExit("sem_init-sem2"); /* Wait for 'sem1' to be posted by peer before touching shared memory. */ if (sem_wait(&shmp->sem1) == -1) errExit("sem_wait"); /* Convert data in shared memory into upper case. */ for (size_t j = 0; j < shmp->cnt; j++) shmp->buf[j] = toupper((unsigned char) shmp->buf[j]); /* Post 'sem2' to tell the peer that it can now access the modified data in shared memory. */ if (sem_post(&shmp->sem2) == -1) errExit("sem_post"); /* Unlink the shared memory object. Even if the peer process is still using the object, this is okay. The object will be removed only after all open references are closed. */ shm_unlink(shmpath); exit(EXIT_SUCCESS); } Source du programme : pshm_ucase_send.c Le programme << send >> accepte deux arguments de ligne de commande : le nom d'un objet en memoire partagee prealablement cree par le programme << bounce >> et une chaine a copier dans cet objet. Le programme ouvre l'objet en memoire partagee et le projette dans son espace d'adressage. Ensuite, il copie les donnees specifiees a l'aide du second argument vers la memoire partagee et poste le premier semaphore pour informer le programme << bounce >> qu'il peut maintenant acceder aux donnees. Lorsque le programme << bounce >> a poste le second semaphore, le programme << send >> affiche le contenu de la memoire partagee sur la sortie standard. /* pshm_ucase_send.c Licensed under GNU General Public License v2 or later. */ #include #include "pshm_ucase.h" int main(int argc, char *argv[]) { int fd; char *shmpath, *string; size_t len; struct shmbuf *shmp; if (argc != 3) { fprintf(stderr, "Usage: %s /shm-path string\n", argv[0]); exit(EXIT_FAILURE); } shmpath = argv[1]; string = argv[2]; len = strlen(string); if (len > BUF_SIZE) { fprintf(stderr, "String is too long\n"); exit(EXIT_FAILURE); } /* Open the existing shared memory object and map it into the caller's address space. */ fd = shm_open(shmpath, O_RDWR, 0); if (fd == -1) errExit("shm_open"); shmp = mmap(NULL, sizeof(*shmp), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (shmp == MAP_FAILED) errExit("mmap"); /* Copy data into the shared memory object. */ shmp->cnt = len; memcpy(&shmp->buf, string, len); /* Tell peer that it can now access shared memory. */ if (sem_post(&shmp->sem1) == -1) errExit("sem_post"); /* Wait until peer says that it has finished accessing the shared memory. */ if (sem_wait(&shmp->sem2) == -1) errExit("sem_wait"); /* Write modified data in shared memory to standard output. */ write(STDOUT_FILENO, &shmp->buf, len); write(STDOUT_FILENO, "\n", 1); exit(EXIT_SUCCESS); } VOIR AUSSI close(2), fchmod(2), fchown(2), fcntl(2), fstat(2), ftruncate(2), memfd_create(2), mmap(2), open(2), umask(2), shm_overview(7) 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 Lucien Gentis 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.06 31 octobre 2023 shm_open(3)