Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Nov 1999 23:44:31 -0500
From:      "Brian J. McGovern" <mcgovern@spoon.beta.com>
To:        hackers@freebsd.org
Subject:   writing to an mmap()'ed region requires read access?
Message-ID:  <199912010444.XAA17911@spoon.beta.com>

next in thread | raw e-mail | index | archive | help
I was just playing with mmap() really for the first time, and I noticed
something a bit odd. When you mmap() a file for writing, it also appears
to require that you give it read permissions, else it dies on a signal 10.
Any reason for this? (I'm using 3.3-STABLE (11/30/99) with the following
program)
	-Brian

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

void main(int argc, char *argv[])
  {
    int			f1  = 0,	/* File descriptor for source */
			f2  = 0;	/* File descriptor for target */
   
    off_t		size = 0,	/* Size of source/mmap'ed regions */
			len = 0;	/* Size of destination (for test) */
    
    unsigned char	*b1 = NULL,	/* MMAP of source */
			*b2 = NULL;	/* MMAP of destination */

    if (argc < 3)			/* Too few arguments? */
      {
        printf("Usage: mcopy <f1> <f2>\n");
	exit(1);
      }
    f1 = open(argv[1],O_RDWR);		/* Open src */
    f2 = open(argv[2],O_RDWR | O_CREAT);/* Open dst */
    if (f1 < 0)				/* Error in src? */
      {
        printf("Couldn't open file %s\n",argv[1]);
	exit(2);
      }
    if (f2 < 0)				/* Error in dst? */
      {
        printf("Couldn't open file %s\n",argv[2]);
	exit(3);
      }
    printf("Both files opened\n");
    size = lseek(f1,0,SEEK_END);	/* How big is src? */
    printf("Size is %d\n",size);
    if (lseek(f2,size - 1,SEEK_SET) != (size - 1))	/* Make dst 1 byte shorter */
      {
        printf("Couldn't seek in output file to location %d\n",size - 1);
	exit(4);
      }
    write(f2,"\0",1);			/* Write single byte, thereby creating a "hole" in the file.
					   This allows u to mmap the entire region
					   by only writing 1 byte */
    len = lseek(f2,0,SEEK_END);		/* Make sure our destination is now as big
					   as our source. This is not required */
    printf("output file should now by %d bytes long\n",len);

    /* MMAP the source */
    b1 = (unsigned char *)mmap((void *)NULL, (size_t)size, PROT_READ, MAP_SHARED, f1, 0);
    if (b1 == MAP_FAILED)
      {
        perror("mmap input file");
	exit(5);
      }
    printf("mmap of file 1 complete. Address is %p.\n",b1);

    /* MMAP the destination. Is read access really required? */
    b2 = (unsigned char *)mmap((void *)NULL, (size_t)size, PROT_READ | PROT_WRITE, MAP_SHARED, f2, 0);
    if (b2 == MAP_FAILED)
      {
        perror("mmap input file");
	exit(5);
      }
    printf("mmap of file 2 complete. Address is %p.\n",b2);
    printf("Performing bcopy\n");
    
    /* Copy the files */
    memcpy(b2,b1,size);
    printf("Unmapping files\n");

    /* Unmap/close them */
    munmap(b1,(size_t)size);
    munmap(b2,(size_t)size);
    printf("Closing descriptors\n");
    close(f1);
    close(f2);
  }


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199912010444.XAA17911>