Subject: Re: Problems with mmap
From: [email-masked] (David Gadbois)

29 Oct 1996 19:21:43 -0800
Sender: [email-masked]
Approved: [email-masked]
Distribution: cygnus
Message-ID: <[email-masked]>
Original-To: [email-masked]
Original-CC: [email-masked]
In-reply-to: <[email-masked]>
	([email-masked])
Original-Sender: [email-masked]

   From: [email-masked]
   Date: 29 Oct 96 15:17:45 (+0000)

   I have a small program which uses the call mmap to map a structure
   to a disk file. The API mmap is defined in sys/mman.h but I get
   error resolving the function. Which ib should I use, the closest I
   gt to the function name is in libmmalloc.a but the actual function
   mmap is still undefined

It is not implemented yet.  The tricky parts are keeping a mapping
from UNIX fd's to NT file handles and figuring out how to get
copy-on-write semantics to work the way you'd expect them to.

Here are the workarounds I use for a couple of stylized cases: Mapping
a file into memory and getting a chunk of memory at a given address.

--David Gadbois

#if defined(__CYGWIN32__)

#include <windows.h>

#ifndef FILE_MAP_COPY
#define FILE_MAP_COPY 1
#endif

caddr_t map_file(char *filename, caddr_t addr, size_t length, off_t offset) {
  HANDLE file_handle, file_mapping;
  LPVOID start;
	
  file_handle = CreateFile(filename,
			   GENERIC_READ | GENERIC_WRITE,
			   FILE_SHARE_READ,
			   NULL,
			   OPEN_EXISTING,
			   FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
			   NULL);
  if (!file_handle) die("Could not open file");
  file_mapping = CreateFileMappingA(file_handle,
				   NULL,
				   PAGE_WRITECOPY,
				   0, 0, 
				   NULL);

  if (!file_mapping) die("Could not create file mapping");
  start = MapViewOfFileEx(file_mapping,
			  FILE_MAP_COPY,
			  0, offset, length, (LPVOID) addr);
  if (!start) die("Could not map the file");
  if (!CloseHandle(file_mapping)) die("Could not close file mapping");
  if (!CloseHandle(file_handle)) die("Could not close file handle");
  return (caddr_t) start;
}

caddr_t get_memory(caddr_t addr, size_t length) {
  HANDLE file_mapping;
  LPVOID start;
	
  /* The (HANDLE) 0xFFFFFFFF bit is Win32's way of doing MAP_ANONYMOUS. */
       file_mapping = CreateFileMappingA((HANDLE) 0xFFFFFFFF,
					NULL,
					PAGE_WRITECOPY,
					0, length, NULL);

  if (!file_mapping) die("Could not create file mapping");
  start = MapViewOfFileEx(file_mapping,
			  FILE_MAP_COPY,
			  0, 0, 0, (LPVOID) addr);
  if (!start) die("Could not map the file");
  if (!CloseHandle(file_mapping)) die("Could not close file mapping");
  return (caddr_t) start;
}

#elif defined(HAVE_MMAP)

#ifdef HAVE_MMAP

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

caddr_t map_file(char *filename, caddr_t addr, size_t length, off_t offset) {
  caddr_t actual_addr;
  int fd;

  if ((fd = open(filename, O_RDONLY)) < 0)
    die("Could not open map file %s", filename);

  actual_addr = mmap((caddr_t) addr,
		     length,
		     PROT_READ | PROT_WRITE,
#ifdef MAP_FILE
		     MAP_FILE |
#endif
#ifdef MAP_PRIVATE
		     MAP_PRIVATE |
#endif
		     MAP_FIXED,
		     fd,
		     (off_t) offset);
  if (actual_addr == (caddr_t) -1)
    die("File mapping failed");

  close(fd);
  return actual_addr;
}

caddr_t get_memory(caddr_t addr, size_t length) {
  caddr_t actual_addr;

#ifdef MAP_ANONYMOUS
  actual_addr = mmap(addr,
		     length,
		     PROT_READ | PROT_WRITE,
#ifdef MAP_PRIVATE
		     MAP_PRIVATE |
#endif /* MAP_PRIVATE */
		     MAP_ANONYMOUS | MAP_FIXED,
		     -1,
		     0);
#else
  /* For some versions of mmap(), you have to map /dev/zero to get the
     effect of MAP_ANONYMOUS. */
    { 
      int fd;
     
      if ((fd = open("/dev/zero", O_RDONLY)) < 0)
	die("Could not open /dev/zero.");

      actual_addr = mmap(addr,
			 length,
			 PROT_READ | PROT_WRITE,
#ifdef MAP_PRIVATE
			 MAP_PRIVATE |
#endif /* MAP_PRIVATE */
			 MAP_FIXED,
			 fd,
			 0);
      close(fd);
    }
#endif /* MAP_ANONYMOUS */
  if (actual_addr == (caddr_t) -1)
    die("Memory mapping failed");
  
  return actual_addr;
}

#else

#error There is no memory mapping facility.

#endif

-
For help on using this list, send a message to
"[email-masked]" with one line of text: "help".