| Summary: | Cant msync memory mapped file onto desk. | ||
|---|---|---|---|
| Product: | Base System | Reporter: | ikqumei <ikqumei> |
| Component: | i386 | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
<<On Mon, 5 Feb 2001 15:58:41 -0800 (PST), ikqumei@computer.org said: > ofbuf = (char*)mmap(NULL, ofsz, PROT_READ|PROT_WRITE, /*MAP_DENYWRITE*/MAP_PRIVATE, hOldFile, 0); You have specified a private memory mapping. Modifications made to such mappings are *never* visible anywhere outside that mapping. Use MAP_SHARED to create a mapping which modifies globally-visible state. -GAWollman State Changed From-To: open->closed Programmer error. Thank you Garrett for the follow-up. I tried your suggestion and it did work. I just wanted to share with you this bit of information. I have originally wrote a similar code for redhat linux 6.2, and it works ok. However, as I went on to port to FreeBSD, I experienced this problem. The man pages confirmed to me your response, so I could conclude that FreeBSD is more strict that Redhat Linux!? Thanks again, Iyad Qumei. ----- Original Message ----- From: "Garrett Wollman" <wollman@khavrinen.lcs.mit.edu> To: <ikqumei@computer.org> Cc: <freebsd-gnats-submit@FreeBSD.ORG> Sent: Monday, February 05, 2001 4:50 PM Subject: i386/24886: Cant msync memory mapped file onto desk. > <<On Mon, 5 Feb 2001 15:58:41 -0800 (PST), ikqumei@computer.org said: > > > ofbuf = (char*)mmap(NULL, ofsz, PROT_READ|PROT_WRITE, /*MAP_DENYWRITE*/MAP_PRIVATE, hOldFile, 0); > > You have specified a private memory mapping. Modifications made to > such mappings are *never* visible anywhere outside that mapping. Use > MAP_SHARED to create a mapping which modifies globally-visible state. > > -GAWollman > > > <<On Wed, 7 Feb 2001 00:06:13 -0800, "Iyad Qumei" <ikqumei@computer.org> said: > The man pages confirmed to me your response, so I could conclude > that FreeBSD is more strict that Redhat Linux!? It's possible that you have found a bug in whatever version of the Linux kernel you were running. The POSIX standard states: If MAP_PRIVATE is specified, modifications to the mapped data by the calling process shall be visible only to the calling process and shall not change the underlying object. It is unspecified whether modifications to the underlying object done after the MAP_PRIVATE mapping is established are visible through the MAP_PRIVATE mapping. FreeBSD implements this behavior as described. -GAWollman |
I wrote a simple program to demonstrate the problem. Basically, I use mmap to exchange information between files. After this is done, I try to msync the information back to desk. The new information does not seem to be saved. The return value from msync is 0, and no error registed through errno. I used simple text files with this program. < source code begin > #include <stdio.h> #include <sys/types.h> #include <sys/uio.h> #include <sys/mman.h> #include <fcntl.h> #include <limits.h> #include <errno.h> #include <unistd.h> bool ResizeFile( int fd, int new_sz ); int main() { int hOldFile=0, hNewFile=0; char *ofbuf=NULL, *nfbuf=NULL; long new_sz=155, ofsz=133; char *ofile="oldf.txt"; char *nfile="newf.txt"; hOldFile = open( ofile, O_RDWR ); hNewFile = open( nfile, O_RDWR ); if( hOldFile ) ofbuf = (char*)mmap(NULL, ofsz, PROT_READ|PROT_WRITE, /*MAP_DENYWRITE*/MAP_PRIVATE, hOldFile, 0); if ( !ResizeFile( hOldFile, new_sz ) ) { close(hOldFile); close(hNewFile); return 1; } nfbuf = (char*) mmap(NULL, new_sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, hNewFile, 0); for( int i=0; i<new_sz; i++ ) ofbuf[i] = nfbuf[i]; if ( msync( ofbuf, /*MPPH.new_sz*/ 0 , MS_SYNC) ) perror( "Error msync ofbuf" ); munmap( ofbuf, new_sz ); close(hOldFile); if( msync( nfbuf, new_sz, MS_SYNC ) ) perror( "Error msync nfbuf" ); munmap( nfbuf, new_sz ); close(hNewFile); } bool SetEndOfFile( int fd ) { long int new_size; new_size = lseek(fd,0L,SEEK_CUR); if( -1 == new_size ) return ( -1 ); if ( write( fd, "\0", 1) <= 0 ) return ( -1 ); if( ftruncate(fd, new_size) != -1 ) return true; return false; } bool ResizeFile( int fd, int new_sz ) { if ( new_sz != lseek( fd, new_sz, SEEK_SET ) ) return false; if (!SetEndOfFile(fd) ) return false; if ( 0 != lseek(fd,0,SEEK_SET)) return false; return true; } How-To-Repeat: I used two text files, <oldf.txt, 133bytes> auto testing: Functional spec and Software design spec as guide to features testing. Generator testing: command line testing. <newf.txt, 155bytes> auto testing: Functional spec and Software design spec as guide to features testing. Generator testing: command line testing. Just added a line.