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>