Skip to content

Commit

Permalink
fix: handle mmap offset
Browse files Browse the repository at this point in the history
add and use offset parameter in doMsync
add test case for shared mmap with offset

fixes emscripten-core#10094
  • Loading branch information
petersalomonsen committed Dec 24, 2019
1 parent 9de3bd4 commit 9e4eb22
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -443,4 +443,5 @@ a license to everyone to use it as detailed in LICENSE.)
* John Granström <[email protected]>
* Clemens Backes <[email protected]> (copyright owned by Google, Inc.)
* Tibor Klajnscek <[email protected]>
* Benjamin Golinvaux <[email protected]>
* Benjamin Golinvaux <[email protected]>
* Peter Salomonsen <[email protected]>
10 changes: 5 additions & 5 deletions src/library_syscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ var SyscallsLibrary = {
{{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i64') }}};
return 0;
},
doMsync: function(addr, stream, len, flags) {
doMsync: function(addr, stream, len, flags, offset) {
var buffer = new Uint8Array(HEAPU8.subarray(addr, addr + len));
FS.msync(stream, buffer, 0, len, flags);
FS.msync(stream, buffer, offset, len, flags);
},
doMkdir: function(path, mode) {
// remove a trailing slash, if one - /a/b/ has basename of '', but
Expand Down Expand Up @@ -254,7 +254,7 @@ var SyscallsLibrary = {
ptr = res.ptr;
allocated = res.allocated;
}
SYSCALLS.mappings[ptr] = { malloc: ptr, len: len, allocated: allocated, fd: fd, flags: flags };
SYSCALLS.mappings[ptr] = { malloc: ptr, len: len, allocated: allocated, fd: fd, flags: flags, offset: off };
return ptr;
},

Expand All @@ -272,7 +272,7 @@ var SyscallsLibrary = {
if (!info) return 0;
if (len === info.len) {
var stream = FS.getStream(info.fd);
SYSCALLS.doMsync(addr, stream, len, info.flags);
SYSCALLS.doMsync(addr, stream, len, info.flags, info.offset);
FS.munmap(stream);
SYSCALLS.mappings[addr] = null;
if (info.allocated) {
Expand Down Expand Up @@ -855,7 +855,7 @@ var SyscallsLibrary = {
var addr = SYSCALLS.get(), len = SYSCALLS.get(), flags = SYSCALLS.get();
var info = SYSCALLS.mappings[addr];
if (!info) return 0;
SYSCALLS.doMsync(addr, FS.getStream(info.fd), len, info.flags);
SYSCALLS.doMsync(addr, FS.getStream(info.fd), len, info.flags, 0);
return 0;
},
__syscall147__deps: ['$PROCINFO'],
Expand Down
50 changes: 50 additions & 0 deletions tests/fs/test_mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,55 @@ int main() {
fclose(fd);
}

// MAP_SHARED with offset
{
const char* text = "written shared mmap with offset";
const char* path = "/yolo/sharedoffset.txt";

int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
assert(fd != -1);

size_t textsize = strlen(text) + 1; // + \0 null character
// offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE).
size_t offset = sysconf(_SC_PAGE_SIZE) * 2;

assert(lseek(fd, textsize + offset - 1, SEEK_SET) != -1);

// need to write something first to allow us to mmap
assert(write(fd, "", 1) != -1);

char *map;
map = (char*)mmap(0, textsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset - 1);
// assert failure if offset is not a multiple of page size
assert(map == MAP_FAILED);

map = (char*)mmap(0, textsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
assert(map != MAP_FAILED);

for (size_t i = 0; i < textsize; i++) {
map[i] = text[i];
}

assert(msync(map, textsize, MS_SYNC) != -1);

assert(munmap(map, textsize) != -1);

close(fd);
}

{
FILE* fd = fopen("/yolo/sharedoffset.txt", "r");
if (fd == NULL) {
printf("failed to open /yolo/sharedoffset.txt\n");
return 1;
}
size_t offset = sysconf(_SC_PAGE_SIZE) * 2;

char buffer[offset + 31];
fread(buffer, 1, offset + 32, fd);
// expect text written from mmap operation to appear at offset in the file
printf("/yolo/sharedoffset.txt content=%s %d\n", buffer + offset, offset);
fclose(fd);
}
return 0;
}
1 change: 1 addition & 0 deletions tests/fs/test_mmap.out
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/yolo/in.txt content=mmap ftw!
/yolo/out.txt content=written mmap
/yolo/private.txt content=
/yolo/sharedoffset.txt content=written shared mmap with offset 32768

0 comments on commit 9e4eb22

Please sign in to comment.