HP OpenVMS Systems

ask the wizard
Content starts here

Compaq C Programming Examples?

» close window

The Question is:

 
 
Where can I find programming examples using the Compaq C 6.4 rtl function mmap?
 Ideally I'd like to see how a cooperating process maps to an existing memory
 region.
 
 
 


The Answer is :

 
  An OpenVMS example of shared memory access based on COMMONs is
  available in Ask The Wizard topic (2486), and an example based
  on system services is available via a link at the top level of
  the Ask The Wizard area.  Here is a Compaq C example of mmap:
 
	--
 
/*
//  Copyright 2001 Compaq Computer Corporation
//
//  This program is an example of using the C RTL routine mmap, and
//  which allows sharing of memory (global sections) in a relatively
//  portable manner.
*/
 
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
 
#define MAXSIZE 10
#define VMSSHROPT
#ifdef __vms
#undef VMSSHROPT
#define VMSSHROPT ,"shr=put"
#endif
 
int main()
  {
  char *filename = tmpnam(NULL);
  int FileChan1, FileChan2;
  int i;
  int RetStat;
 
  struct
    {
    int DataArray[MAXSIZE];
    } Mmap0, *MmapPtr1, *MmapPtr2;
 
  // Initialize the data in the array
  //
  for ( i = 0; i < MAXSIZE; i++ )
    Mmap0.DataArray[i] = i;
 
  // create the file.  Permit write sharing.
  //
  FileChan1 = open( filename, O_RDWR | O_CREAT, 0777 VMSSHROPT );
  if ( FileChan1 == -1 ) perror("1? open");
 
  // Open another channel to the same file, using the write-sharing.
  //
  FileChan2 = open( filename, O_RDWR, 0777 VMSSHROPT );
  if ( FileChan2 == -1 ) perror("2? open");
 
  // write the data into the file
  //
  RetStat = write( FileChan1, &Mmap0, sizeof ( Mmap0 ) );
  if ( RetStat != sizeof ( Mmap0 ))
    perror( "error writing initial data to file..." );
 
  // flush the data out of the cache, and into the file.
  //
  if ( fsync ( FileChan1 ) )
    perror( "error flushing the file..." );
 
  // Map the file to a shared memory section.
  //
  // By specifying NULL as the first parameter and by using the MAP_VARIABLE
  // flag, we let the operating system pick the virtual address range where
  // the section will be mapped.
  //
  // In OpenVMS, the equivalent of this option on the $crmpsc and $mgblsc
  // calls is the SEC$M_EXPREG expand-region flag.
  //
  MmapPtr1 = mmap( NULL,                   // let the OS pick the address
                   sizeof( Mmap0 ),        // size of the data
                   PROT_WRITE,             // permit write sharing
                   MAP_VARIABLE | MAP_SHARED,
                   FileChan1,              // file id
                   0 );                    // offset into the file
  if ( MmapPtr1 == MAP_FAILED )
    perror("1? mmap");
 
  // Map the file again.
  //
  MmapPtr2 = mmap( NULL,
                   sizeof( *MmapPtr2 ),
                   PROT_WRITE,
                   MAP_VARIABLE | MAP_SHARED,
                   FileChan2, 0 );
  if ( MmapPtr2 == MAP_FAILED )
    perror("1? mmap");
 
  // Now use both windows to demonstrate shared access into the data.
  //
  printf( "++ The view through the first window...\n");
  for ( i = 0; i < MAXSIZE; i++ )
    printf ( "  DataArray[%d] = %d\n", i, MmapPtr1->DataArray[i] );
 
  printf( "++ The view through the second window...\n");
  for ( i = 0; i < MAXSIZE; i++ )
    printf ( "  DataArray[%d] = %d\n", i, MmapPtr2->DataArray[i] );
 
  printf( "++ Increment the data via the second window...\n");
  for ( i = 0; i < MAXSIZE; i++ )
    MmapPtr2->DataArray[i]++;
 
  printf( "++ The view through the first window...\n");
  for ( i = 0; i < MAXSIZE; i++ )
    printf ( "  DataArray[%d] = %d\n", i, MmapPtr1->DataArray[i] );
 
  printf( "Cleaning up for exit...\n");
 
  //  Close and unmap the file.
  //
  if ( close( FileChan1 ) ) perror("1? close");
  if ( close( FileChan2 ) ) perror("2? close");
  if ( munmap( MmapPtr1, sizeof( *MmapPtr1 )) ) perror("1? munmap");
  if ( munmap( MmapPtr2, sizeof( *MmapPtr2 )) ) perror("2? munmap");
  if ( remove( filename ) ) perror("remove");
 
  printf( "Done...\n");
 
  return EXIT_SUCCESS;
  }
 

answer written or last revised on ( 10-AUG-2001 )

» close window