Chapter Contents

Previous

Next
mmap

mmap



Map an HFS File into Memory

Portability: UNIX compatible


SYNOPSIS
DESCRIPTION
RETURN VALUE
USAGE NOTES
EXAMPLE
RELATED FUNCTIONS


SYNOPSIS

#include <mman.h>
void *mmap(void *addr, size_t len, 
           int prot, int flags, 
           int fd, off_t offset);


DESCRIPTION

The mmap function is used to request memory mapping of all or part of an HFS file. Memory mapping allocates a block of memory so that fetching from the memory block will obtain the corresponding bytes of the file. Depending on the mmap flags, memory mapping is capable of changing the corresponding bytes of the file when data is stored in the memory block.

The addr argument may be either 0 or a memory address. If addr is 0, the system will map the file anywhere in memory it chooses. If addr is not 0 , the system will attempt to allocate the memory for the file mapping near the address specified.

The len argument specifies the number of bytes of the file that are to be mapped. The length must not cause the map to extend beyond the end of the file. If the length does not specify an integral number of pages, the map is extended to the next highest page boundary, and the additional space is set to binary zeroes.

The prot argument specifies the protection status of the mapped memory. It should be specified as one of the symbolic constants:

You cannot specify PROT_WRITE if the file descriptor for the file does not permit writing.

Note:   The protection status of the mapped memory can be changed later by a call to the mprotect function.  [cautionend]
The flags argument specifies one or more option flags, combined using the or operator (|). Each flag should be specified as one of the following symbolic constants:

The fd argument specifies an open file descriptor for the file to be mapped, which must be a regular HFS file.

The offset argument specifies the first byte of the file to be mapped. The offset must be an exact multiple of the system page size (4096 bytes).

Note:   See the IBM UNIX System Services Assembler Callable Services manual for additional information about the behavior of mmap and the conditions under which it can be used.  [cautionend]


RETURN VALUE

mmap returns the address of the start of the mapped memory if successful, or 0 if unsuccessful.


USAGE NOTES

The mmap function can only be used with MVS 5.2.2 or a later release.


EXAMPLE

/*--------------------------------------+
| POSIX/UNIX header files               |
+---------------------------------------*/
#include <unistd.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/mman.h>

/*--------------------------------------+
| ISO/ANSI header files                 |
+--------------------------------------*/
#include <stdlib.h>

#include <stdio.h>

/*--------------------------------------+
| Types                                 |
+--------------------------------------*/

/*--------------------------------------+
| Constants                             |
+--------------------------------------*/
#define F_MODE 
 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

/*--------------------------------------+
| Name:      main                       |
| Returns:   exit(EXIT_SUCCESS) or      *
|            exit(EXIT_FAILURE)         |
+--------------------------------------*/
int main( int argc, char **argv )
{
/* file descripter for the src file    */
    int fdSrc;                 

/* file descripter for the dest file   */
    int fdDest;  
              
/* memory addr of the mapped src file  */
    char *src;                 

/* memory addr of the mapped dest file */
    char *dest;                

/* Buffer for fstat() info             */
    struct stat statBuffer;    

/*--------------------------------------*/
/* test args to main                    */
/*--------------------------------------*/
   if ( argc != 3 )
   {
      fprintf(stderr, "Usage: mmcp  \n");
      exit(EXIT_FAILURE);
   }

/*-----------------------------------*/
/* open the source file for read     */
/*-----------------------------------*/
   if ( (fdSrc = open(argv[1], O_RDONLY)) < 0 )
   {
    fprintf(stderr,
     "ERROR: Cannot open source file <%s>\n", 
        argv[1]);
       exit(EXIT_FAILURE);
   }

/*------------------------------------*/
/* open/create new file for output    */
/*------------------------------------*/
if ( (fdDest = 
open(argv[2], O_RDWR | O_CREAT 
 | O_TRUNC, F_MODE)) < 0)
   {
 fprintf(stderr,
  "ERROR: 
   Cannot create dest file <%s>\n", argv[1]);
    exit(EXIT_FAILURE);
   }
 
/*--------------------------------------*/
/* retrieve size of source file from    */
/* fstat() function                     */
/*--------------------------------------*/
   if ( fstat(fdSrc, &statBuffer) < 0 )
   {
   fprintf(stderr,
   "ERROR: 
   Cannot fstat source file <%s>\n", argv[1]);
   exit(EXIT_FAILURE);
   }

/*---------------------------------------------*/
/* set the size of the dest file.             */ 
/* If we don't we'll get an                    */
/* SIGSEGV when we try to copy to its mmap.    */
/*---------------------------------------------*/
 if ( ftruncate( fdDest, 
  (off_t)statBuffer.st_size ) < 0 )
   {
   fprintf(stderr,
   "ERROR: 
   Cannot set size of the dest file <%s>\n", 
   argv[2]);
   exit(EXIT_FAILURE);
   }

/*----------------------------------------------*/
/* map the source file to memory                */
/* (for read only)                              */
/*----------------------------------------------*/
if ( (src = mmap(0, 
     statBuffer.st_size, PROT_READ, MAP_SHARED,
        fdSrc, 0)) == (char *)-1)
   {
   fprintf(stderr,
   "ERROR: Cannot memory map source file <%s>\n", 
   argv[1]);
   exit(EXIT_FAILURE);
   }
   else
   {
   printf
   ("NOTE: source file <%s> mapped 
   at address <%p>\n", argv[1], src);
   }

/*----------------------------------------------*/
/* map the dest file to memory                  */
/* (for read only)                              */
/*----------------------------------------------*/
 if ( (dest = mmap
  (0, statBuffer.st_size, PROT_READ,
          MAP_SHARED, fdDest, 0)) == (char *)-1)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot memory map dest file <%s>\n", argv[2]);
   exit(EXIT_FAILURE);
   }
   else
   {
   printf("NOTE: 
   dest file <%s> mapped at address <%p>\n",
   argv[2], dest);
   }

/*-----------------------------------------------*/
/* chg the protection of memory map of           */
/* the dest file to write                        */
/*-----------------------------------------------*/
if ( (mprotect(dest, 
  statBuffer.st_size, PROT_WRITE)) == -1)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot change memory map protect of 
   dest file <%s>\n", argv[2]);
   exit(EXIT_FAILURE);
   }

/*------------------------------------------*/
/* copy src to dest in memory               */
/*------------------------------------------*/
   memcpy(dest, src, statBuffer.st_size);

/*-------------------------------------------*/
/* synchronize the memory mapped dest file.  */
/*-------------------------------------------*/
 if ( (msync
  (dest, statBuffer.st_size, MS_SYNC)) == -1)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot synchronize memory map of 
   dest file <%s>\n", argv[2]);
   exit(EXIT_FAILURE);
   }

/*--------------------------------------------*/
/* cancel mapping of memory to the src file.  */
/*--------------------------------------------*/
   if ( (munmap(src, statBuffer.st_size)) == -1)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot terminate memory map of 
   src file <%s>\n", argv[2]);
   exit(EXIT_FAILURE);
   }

/*--------------------------------------------*/
/* cancel mapping of memory to the dest file. */
/*--------------------------------------------*/
   if ( (munmap(dest, statBuffer.st_size)) == -1)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot terminate memory map of 
   dest file <%s>\n", argv[2]);
   exit(EXIT_FAILURE);
   }

   exit(EXIT_SUCCESS);

}  /* end of main() */

/* end of mmcp.c */


RELATED FUNCTIONS

mprotect , msync , munmap


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.