dwww Home | Manual pages | Find package

shm_open(3)                Library Functions Manual                shm_open(3)

NOM
       shm_open, shm_unlink - Créer, ouvrir ou supprimer des objets en mémoire
       partagée POSIX

BIBLIOTHÈQUE
       Bibliothèque de temps réel (librt, -lrt)

SYNOPSIS
       #include <sys/mman.h>
       #include <sys/stat.h>        /* Pour les constantes de mode */
       #include <fcntl.h>           /*  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() crée et ouvre un nouvel objet en mémoire  parta-
       gée  POSIX, ou ouvre un objet existant. Il s'agit d'un descripteur uti-
       lisable par des processus indépendants pour projeter la même région mé-
       moire à l'aide de mmap(2). La fonction shm_unlink() réalise l'opération
       inverse en supprimant l'objet créé précédemment par shm_open().

       Le fonctionnement de shm_open() est analogue à celui  de  open(2).  nom
       indique  l'objet  en  mémoire partagée à créer ou ouvrir. Pour un fonc-
       tionnement portable, un objet en mémoire partagée doit  être  identifié
       par  un nom au format /un_nom ; c'est-à-dire une chaîne terminée par un
       octet de valeur zéro d'au plus NAME_MAX (c'est-à-dire 255)  caractères,
       et  commençant  par  une barre oblique (« / ») suivie d'un caractère ou
       plus, ces derniers n'étant pas des barres obliques.

       masque est un masque de bits associant à l'aide d'un OU logique une  et
       une seule des deux constantes O_RDONLY ou O_RDWR et un ou plusieurs des
       attributs décrits ci-après :

       O_RDONLY
              Ouvrir l'objet en lecture seule. Un tel  objet  ne  pourra  être
              projeté  en  mémoire  avec  mmap(2)  qu'avec un accès en lecture
              (PROT_READ).

       O_RDWR Ouvrir l'objet en lecture et écriture.

       O_CREAT
              Créer l'objet en mémoire partagée s'il n'existe pas.  L'utilisa-
              teur  et  le  groupe propriétaires de l'objet proviennent des ID
              effectifs du processus appelant, et les bits de permission  sont
              définis  en fonction des 9 bits de poids faible de mode, excepté
              que les bits qui sont définis dans le masque de mode de  fichier
              pour  la création du processus (consultez umask(2)) sont effacés
              pour le nouvel objet. Un jeu de constantes  de  macroutilisables
              pour  définir  le  mode est décrit dans open(2) (les définitions
              symboliques de ces constantes peuvent être obtenues en  incluant
              <sys/stat.h>).

              A new shared memory object initially has zero length—the size of
              the object can be set using ftruncate(2).  The  newly  allocated
              bytes of a shared memory object are automatically initialized to
              0.

       O_EXCL Si O_CREAT était aussi précisé et si un objet en mémoire  parta-
              gée  avec le même nom existait déjà, renvoyer une erreur. La vé-
              rification  de  l'existence  de  l'objet  et  sa  création  s'il
              n'existe pas sont réalisées de manière atomique.

       O_TRUNC
              Si l'objet en mémoire partagée existe déjà, tronquer sa taille à
              zéro.

       Les définitions des valeurs de ces attributs peuvent être  obtenues  en
       incluant <fcntl.h>.

       Si  elle réussit, la fonction shm_open() renvoie un nouveau descripteur
       de fichierréférençant l'objet en mémoire partagée. Ce descripteur  sera
       le  plus petit numéro disponible dans la table des descripteurs du pro-
       cessus. L'attribut FD_CLOEXEC (consultez fcntl(2)) sera activé pour  le
       descripteur de fichier.

       Le descripteur de fichier est utilisé normalement pour les appels ulté-
       rieurs à ftruncate(2) (pour un objet  nouvellement  créé)  et  mmap(2).
       Après  un  appel à mmap(2) le descripteur peut être fermé sans affecter
       la projection mémoire.

       Le fonctionnement de shm_unlink() est analogue à celui  de  unlink(2) :
       il  supprime  le  nom  d'un objet en mémoire partagée, et, une fois que
       tous les processus ont supprimé leur projection en mémoire,  libère  et
       détruit  le  contenu  de la portion de mémoire associée. Après un appel
       réussi à shm_unlink(), les tentatives d'appeler shm_open() avec le même
       nom  échoueront (sauf si O_CREAT est spécifié, auquel cas un nouvel ob-
       jet distinct sera créé).

VALEUR RENVOYÉE
       Si elles réussissent, shm_open() renvoie un descripteur de fichier  (un
       entier  non  négatif)  et  shm_unlink() renvoie  0. En cas d'échec, les
       deux fonctions renvoient -1 et définissent errno pour indiquer le  code
       d'erreur.

ERREURS
       EACCES La  permission  d'utiliser  shm_unlink()  sur l'objet en mémoire
              partagée a été refusée.

       EACCES L'utilisation de shm_open() pour ouvrir l'objet nom dans le mode
              spécifié  a été refusée, ou O_TRUNC a été spécifié et l'appelant
              n'a pas les permissions d'écriture sur l'objet.

       EEXIST O_CREAT et O_EXCL ont été spécifiés dans shm_open() et un  objet
              de mémoire partagée du même nom existe déjà.

       EINVAL L'argument nom de shm_open() n'était pas valable.

       EMFILE La  limite du nombre de descripteurs de fichiers par processus a
              été atteinte.

       ENAMETOOLONG
              La longueur du nom dépasse PATH_MAX.

       ENFILE La limite du nombre total de fichiers ouverts  pour  le  système
              entier a été atteinte.

       ENOENT Tentative  d'ouvrir  avec  shm_open()  un objet nom qui n'existe
              pas, alors que l'attribut O_CREAT n'a pas été spécifié.

       ENOENT Tentative d'utiliser shm_unlink() sur un objet nom qui  n'existe
              pas.

VERSIONS
       Ces fonctions sont fournies depuis la glibc 2.2.

ATTRIBUTS
       Pour  une explication des termes utilisés dans cette section, consulter
       attributes(7).

       ┌──────────────────────────────┬──────────────────────┬────────────────┐
       │InterfaceAttributValeur         │
       ├──────────────────────────────┼──────────────────────┼────────────────┤
       │shm_open(), shm_unlink()      │ Sécurité des threads │ MT-Safe locale │
       └──────────────────────────────┴──────────────────────┴────────────────┘

STANDARDS
       POSIX.1-2001, POSIX.1-2008.

       POSIX.1-2001 indique que le groupe propriétaire d'un objet  en  mémoire
       partagée nouvellement créé utilise soit l'ID de groupe du processus ap-
       pelant, soit un « ID de groupe par défaut défini par le système ».  PO-
       SIX.1-2008  indique  que  le  groupe propriétaire peut être défini soit
       avec l'ID de groupe du processus appelant, soit, si l'objet est visible
       dans le système de fichiers, avec l'ID de groupe du répertoire parent.

NOTES
       POSIX  leaves  the  behavior of the combination of O_RDONLY and O_TRUNC
       unspecified. On Linux, this will successfully truncate an existing sha-
       red memory object—this may not be so on other UNIX systems.

       L'implémentation  sous  Linux des objets de mémoire partagée POSIX uti-
       lise un système de fichiers tmpfs(5)  dédié,  monté  en  principe  sous
       /dev/shm.

EXEMPLES
       Les  programmes  ci-dessous  utilisent la mémoire partagée POSIX et des
       sémaphores non nommés POSIX pour échanger  des  données.  Le  programme
       « bounce »  (qui  doit  être  exécuté en premier) illustre le cas d'une
       chaîne placée en mémoire partagée par le  programme  « send ».  Lorsque
       les données ont été modifiées, le programme « send » affiche le contenu
       de la mémoire partagée modifié. Voici un exemple d'exécution  des  deux
       programmes :

           $ ./pshm_ucase_bounce /myshm &
           [1] 270171
           $ ./pshm_ucase_send /myshm bonjour
           BONJOUR

       Vous trouverez plus de détails à propos de ces programmes ci-dessous.

   Source du programme : pshm_ucase.h
       Ce  fichier d'en-tête est inclus par les deux programmes ci-dessous. Sa
       principale fonction consiste à définir une structure qui sera imposée à
       l'objet en mémoire partagé entre les deux programmes.

           #include <fcntl.h>
           #include <semaphore.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <sys/mman.h>
           #include <sys/stat.h>
           #include <unistd.h>

           #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                                   } while (0)

           #define BUF_SIZE 1024   /* Taille maximale de la chaîne échangée */

           /* Définir une structure qui sera imposée à l'objet
              en mémoire partagée */

           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 » crée un nouvel objet en mémoire partagée avec
       le nom spécifié comme argument de la ligne de  commande  et  le  dimen-
       sionne de manière à correspondre à la taille de la structure shmbuf dé-
       finie dans le fichier d'en-tête. Il projette ensuite l'objet dans l'es-
       pace d'adressage du processus et initialise deux sémaphores POSIX à 0 à
       l'intérieur de l'objet.

       Une fois le premier sémaphore posté par le programme « send », le  pro-
       gramme  « bounce »  met en capitales les données placées en mémoire par
       le programme « send », puis poste le second sémaphore pour indiquer  au
       programme « send » qu'il peut maintenant accéder à la mémoire partagée.

           /* pshm_ucase_bounce.c

              Licensed under GNU General Public License v2 or later.
           */
           #include <ctype.h>

           #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];

               /* Créer l'objet en mémoire partagée et le dimensionner
                  à la taille de notre 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");

               /* Initialiser les sémaphores comme partagés entre processus avec
                  la valeur 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");

               /* Convertir en capitales les données en mémoire partagée. */

               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");

              /* Supprimer le lien avec l'objet en mémoire partagée. Cela ne posera
                 pas de problème, même si le processus pair utilise encore l'objet,
                 car ce dernier ne sera supprimé que lorsque tous les liens ouverts
                 qui y font référence auront été fermés. */

               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 mémoire partagée préalablement créé par le  programme
       « bounce » et une chaîne à copier dans cet objet.

       Le  programme ouvre l'objet en mémoire partagée et le projette dans son
       espace d'adressage. Ensuite, il copie les données spécifiées  à  l'aide
       du  second  argument vers la mémoire partagée et poste le premier séma-
       phore pour informer le programme « bounce » qu'il peut maintenant accé-
       der  aux données. Lorsque le programme « bounce » a posté le second sé-
       maphore, le programme « send » affiche le contenu de la mémoire  parta-
       gée sur la sortie standard.

           /* pshm_ucase_send.c

              Licensed under GNU General Public License v2 or later.
           */
           #include <string.h>

           #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, "La chaîne est trop longue\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");

               /* Copier les données dans l'objet en mémoire partagée. */

               shmp->cnt = len;
               memcpy(&shmp->buf, string, len);

               /* Informer le processus pair qu'il peut maintenant accéder à
                   la mémoire partagée. */

               if (sem_post(&shmp->sem1) == -1)
                   errExit("sem_post");

               /* Attendre que le processus pair indique qu'il a fini d'accéder
                  à la mémoire partagée. */

               if (sem_wait(&shmp->sem2) == -1)
                   errExit("sem_wait");

               /* Afficher les données qui ont été modifiées en mémoire partagée
                  sur la sortie standard. */

               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 française de cette page de manuel a été créée par  Chris-
       tophe  Blaess  <https://www.blaess.fr/christophe/>, Stéphan Rafin <ste-
       phan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, Fran-
       çois  Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Gué-
       rard <fevrier@tigreraye.org>, Jean-Luc  Coulon  (f5ibh)  <jean-luc.cou-
       lon@wanadoo.fr>,  Julien  Cristau <jcristau@debian.org>, Thomas Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François  <nicolas.francois@centra-
       liens.net>,  Florentin  Duneau <fduneau@gmail.com>, Simon Paillard <si-
       mon.paillard@resel.enst-bretagne.fr>,   Denis   Barbier    <barbier@de-
       bian.org>,  David  Prévot  <david@tilapin.org>  et  Lucien  Gentis <lu-
       cien.gentis@waika9.com>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la        GNU        General       Public       License       version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ concernant  les  conditions
       de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si  vous découvrez un bogue dans la traduction de cette page de manuel,
       veuillez envoyer un message à ⟨debian-l10n-french@lists.debian.org⟩.

Pages du manuel de Linux 6.03   5 février 2023                     shm_open(3)

Generated by dwww version 1.15 on Sat Jun 29 01:47:05 CEST 2024.