Provided by: manpages-fr-dev_4.15.0-9_all bug

NOM

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

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

       Éditer les liens avec -lrt.

DESCRIPTION

       La  fonction  shm_open() crée et ouvre un nouvel objet en mémoire partagée POSIX, ou ouvre
       un objet existant. Il s'agit d'un descripteur utilisable 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 fonctionnement 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'utilisateur 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>).

              Un nouvel objet en mémoire partagée a une taille initiale nulle —  elle  peut  être
              définie  avec  ftruncate(2). Les octets d'un objet en mémoire partagée nouvellement
              créé sont automatiquement initialisés à zéro.

       O_EXCL Si O_CREAT était aussi précisé et si un objet en mémoire partagé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 processus. 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 objet 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 │
       └─────────────────────────────────────────────────┴──────────────────────┴────────────────┘

CONFORMITÉ

       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  appelant,  soit  un  « ID  de
       groupe par défaut défini par le système ». POSIX.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 ne précise pas le comportement de la combinaison O_RDONLY et O_TRUNC. Sous Linux, la
       troncature aura lieu — cela n'est pas nécessairement le cas sous d'autres systèmes UNIX.

       L'implémentation sous Linux des objets de mémoire partagée POSIX  utilise  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 <sys/mman.h>
           #include <fcntl.h>
           #include <semaphore.h>
           #include <sys/stat.h>
           #include <stdio.h>
           #include <stdlib.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;            /* Sémaphore POSIX non nommé */
               sem_t  sem2;            /* Sémaphore POSIX non nommé */
               size_t cnt;             /* Nombre d'octets utilisés dans 'buf' */
               char   buf[BUF_SIZE];   /* Données en cours de transfert */
           };

   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 dimensionne 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'espace 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 programme « 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[])
           {
               if (argc != 2) {
                   fprintf(stderr, "Usage: %s /shm-path\n", argv[0]);
                   exit(EXIT_FAILURE);
               }

               char *shmpath = argv[1];

               /* Créer l'objet en mémoire partagée et le dimensionner
                  à la taille de notre structure. */

               int fd = shm_open(shmpath, O_CREAT | O_EXCL | O_RDWR,
                                 S_IRUSR | S_IWUSR);
               if (fd == -1)
                   errExit("shm_open");

               if (ftruncate(fd, sizeof(struct shmbuf)) == -1)
                   errExit("ftruncate");

               /* Projeter l'objet dans l'espace d'adressage de l'appelant. */

               struct shmbuf *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");

               /* Attendre que 'sem1' ait été posté par le processus pair
                  avant de toucher à la mémoire partagée. */

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

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

               for (int j = 0; j < shmp->cnt; j++)
                   shmp->buf[j] = toupper((unsigned char) shmp->buf[j]);

               /* Poster 'sem2' pour informer le processus pair qu'il peut
                  dorénavant accéder aux données modifiées en mémoire partagée. */

               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émaphore 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 partagé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[])
           {
               if (argc != 3) {
                   fprintf(stderr, "Usage: %s /shm-path string\n", argv[0]);
                   exit(EXIT_FAILURE);
               }

               char *shmpath = argv[1];
               char *string = argv[2];
               size_t len = strlen(string);

               if (len > BUF_SIZE) {
                   fprintf(stderr, "La chaîne est trop longue\n");
                   exit(EXIT_FAILURE);
               }

               /* Ouvrir l'objet en mémoire partagée existant et le projeter
                  dans l'espace d'adressage de l'appelant. */

               int fd = shm_open(shmpath, O_RDWR, 0);
               if (fd == -1)
                   errExit("shm_open");

               struct shmbuf *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)

COLOPHON

       Cette page fait partie de la publication 5.13 du projet man-pages Linux.  Une  description
       du  projet et des instructions pour signaler des anomalies et la dernière version de cette
       page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

       La traduction française de cette  page  de  manuel  a  été  créée  par  Christophe  Blaess
       <https://www.blaess.fr/christophe/>,  Stéphan  Rafin  <stephan.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.coulon@wanadoo.fr>,   Julien    Cristau    <jcristau@debian.org>,    Thomas    Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,  Denis
       Barbier   <barbier@debian.org>,   David   Prévot   <david@tilapin.org>  et  Lucien  Gentis
       <lucien.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⟩.