Skip to content

Commit

Permalink
Handle mmap offset (emscripten-core#10095)
Browse files Browse the repository at this point in the history
Add and use offset parameter in doMsync

fixes emscripten-core#10094
  • Loading branch information
petersalomonsen authored and kripken committed Jan 6, 2020
1 parent 13733d3 commit cab9e53
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -444,4 +444,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Clemens Backes <[email protected]> (copyright owned by Google, Inc.)
* Tibor Klajnscek <[email protected]>
* Benjamin Golinvaux <[email protected]>
* Peter Salomonsen <[email protected]>
* Niklas Fiekas <[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 cab9e53

Please sign in to comment.