summaryrefslogtreecommitdiff
path: root/libc-bottom-half
diff options
context:
space:
mode:
Diffstat (limited to 'libc-bottom-half')
-rw-r--r--libc-bottom-half/mman/mman.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/libc-bottom-half/mman/mman.c b/libc-bottom-half/mman/mman.c
index 87f08ba..32bce04 100644
--- a/libc-bottom-half/mman/mman.c
+++ b/libc-bottom-half/mman/mman.c
@@ -21,6 +21,7 @@ struct map {
int flags;
off_t offset;
size_t length;
+ int fd;
};
void *mmap(void *addr, size_t length, int prot, int flags,
@@ -90,6 +91,17 @@ void *mmap(void *addr, size_t length, int prot, int flags,
// or with zeros.
addr = map + 1;
if ((flags & MAP_ANON) == 0) {
+ int new_fd = dup(fd);
+
+ if (new_fd < 0) {
+ errno = EINVAL;
+ free(map);
+
+ return NULL;
+ }
+
+ map->fd = new_fd;
+
char *body = (char *)addr;
while (length > 0) {
const ssize_t nread = pread(fd, body, length, offset);
@@ -105,6 +117,7 @@ void *mmap(void *addr, size_t length, int prot, int flags,
body += (size_t)nread;
}
} else {
+ map->fd = -1;
memset(addr, 0, length);
}
@@ -123,6 +136,54 @@ int munmap(void *addr, size_t length) {
// Release the memory.
free(map);
+ // Write the data back to the backing file and close
+ // the file handle
+ if (map->fd > 0) {
+ if ((map->prot & PROT_WRITE) != 0) {
+ msync(addr, length, MS_SYNC);
+ }
+
+ close(map->fd);
+ }
+
// Success!
return 0;
}
+
+int msync (void *addr, size_t length, int flags) {
+ struct map *map = (struct map *)addr - 1;
+ size_t map_flags = map->flags;
+ off_t map_offset = map->offset;
+ size_t map_length = map->length;
+ int fd = map->fd;
+
+ if (length > map_length) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((map->prot & PROT_WRITE) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((map_flags & MAP_ANON) == 0) {
+ char *body = (char *)addr;
+
+ while (length > 0) {
+ const ssize_t nwrite = pwrite(fd, body, length, map_offset);
+
+ if (nwrite > 0) {
+ length -= (size_t)nwrite;
+ map_offset += (size_t)nwrite;
+ body += (size_t)nwrite;
+ } else if (errno == EINTR) {
+ continue;
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}