local/shared.c

///////////////////////////////////////////////////////////////////////////////
// Filename: shared.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: show how UNIX shared memory works
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/06 00:28:57 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////


// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */



// System headers /////////////////////////////////////////// System headers //

#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#include <unistd.h>


// Local headers ///////////////////////////////////////////// Local headers //

#include "../common.h"



// Macros /////////////////////////////////////////////////////////// Macros //
    /* NONE */



// File scope objects /////////////////////////////////// File scope objects //

const int SHM_SIZE = 1000;
const int SHM_MODE = (SHM_R | SHM_W);       // user read/write

                                // two equal long strings to display
const char *STRING1 = "Hello, World!        ";  
const char *STRING2 = "Hello, changed World!";  



// External variables, functions, and classes ///////////// External objects //
    /* NONE */



// Signal catching functions ///////////////////// Signal catching functions //
    /* NONE */



// Structures, unions, and class definitions /////////////////// Definitions //
    /* NONE */



// Functions and class implementation /// Functions and class implementation //
    /* NONE */



// Main /////////////////////////////////////////////////////////////// Main //

/* This program demonstrates how two different processes can access
 * shared memory. They do not synchronize their access. This is normally
 * done with semaphores. 
 */

int
main(int argc, char *argv[])
{
    error.set_program_name(argv[0]);    

    int     shmid;
    char    *shmptr;

    // set up shared memory

    if( (shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0)
        error.system("shmget error");
    
    if( (shmptr = (char *)shmat(shmid, 0, 0)) == (void *) -1)   
        error.system("shmat error");


    // initialize memory that we use for communication 

    strcpy(shmptr, STRING1);

    pid_t child;

    if( (child = fork() ) < 0)
        error.system("fork error");

    if(child == 0)
    {
        /* child */

        // wait a little bit
        sleep(3);

        // change memory a bit

        strcpy(shmptr, STRING2);

        sleep(2);

        // and change back to original string

        strcpy(shmptr, STRING1);
    }
    else
    {
        /* parent */

        // display memory location for 10 seconds

        time_t t=time(NULL);        // get time

        while((time(NULL) - t) < 10)
        {
            cout << shmptr << "\r" << flush;
        }

        cout << endl;

        // destry shared memory

        if (shmdt(shmptr) == -1)
            error.system("shmdt error");

        if (shmctl(shmid, IPC_RMID, 0) == -1)
            error.system("shmctl error");
    }
    


    return(EXIT_SUCCESS);
}