/*
 * shmdemo.c -- utilisation de la mémoire partagée en C
 * exemple simple :
 *   - si le programme est utilisé sans aucun argument, il lit le contenu du
 *     segment de mémoire partagée.
 *   - le le programme est utilisé avec un argument de type « chaine de
 *     caractères », alors le programme stocke cet argument dans le segment
 *     partagé
 */


/* inclusion des librairies standards... */
#include <stdio.h>           /* "standard Input Output" */
#include <stdlib.h>          /* "standard libraries" */
#include <string.h>          /* fonctions standards sur les chaînes */


/*
 * Les trois libraries suivantes sont nécessaires pour les opérations
 * « système ». En particulier, "ipc" veut dire "Inter Process
 * Communications", et "shm" veut dire "shared memory".
 */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>


/* On va seulement utiliser 1024 octets (1K) pour le segment partagé : on
 * définit une constante de taille. */
#define TAILLE_SHM 1024


/*
 * la fonction principale prend des arguments : argc contient le nombre
 * d'arguments, et argv est un pointeur vers les arguments
 */
int main(int argc, char *argv[])
{
    key_t key;
    int shmid;
    char *data;
    int mode;

    /* erreur s'il y a plus que deux arguments */
    if (argc > 2) {
        fprintf(stderr, "utilisation : shmdemo [chaîne]\n");
        exit(1);
    }

    /* création de la clé */
    if ((key = ftok("shmdemo.c", 'R')) == -1) {
        perror("ftok");
        exit(1);
    }

    /* allocation du segment de mémoire partagée */
    if ((shmid = shmget(key, TAILLE_SHM, 0644 | IPC_CREAT)) == -1) {
        perror("shmget");
        exit(1);
    }

    /* récupération d'un pointeur vers ce segment de mémoire partagée */
    data = shmat(shmid, (void *)0, 0);
    if (data == (char *)(-1)) {
        perror("shmat");
        exit(1);
    }

    /* suivant le nombre d'arguments (0 ou 1), on lit le contenu du segment,
     * ou on écrit l'argument dessus. */
    if (argc == 2) {
        printf("écriture de \"%s\" en mémoire partagée\n", argv[1]);
        strncpy(data, argv[1], TAILLE_SHM);  /* copie de l'argument */
    } else
        printf("contenu de la mémoire partagée : \"%s\"\n", data);


    /* avant de terminer, on « détache » le segment de mémoire partagée. */
    if (shmdt(data) == -1) {
        perror("shmdt");
        exit(1);
    }

    return 0;
}




