Nucleus
Barry Improved page fault handling and mmap system call 665af0a (3 years, 2 months ago)
diff --git a/memory/mmap.c b/memory/mmap.c
new file mode 100644
index 0000000..b7a99eb
--- /dev/null
+++ b/memory/mmap.c
@@ -0,0 +1,53 @@
+/*
+ * This file implements the mmap() routine. It takes the parameters and sets up
+ * the relevant memory regions. If no address is passed it will find the first
+ * available one and use it.
+ */
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <nucleus/object.h>
+#include <nucleus/memory.h>
+#include <nucleus/task.h>
+#include <nucleus/vfs.h>
+#include "namespace.h"
+
+/* Map an object into memory */
+void *
+mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
+{
+ VMRegion *region = NULL;
+
+ /* Find gap big enough */
+ if (!addr) {
+ VMRegion *head;
+ foreach (current->vm->regions, head) {
+ if (region && (head->start - region->end >= len))
+ break;
+ region = head;
+ }
+ if (!head && region->end + len >= 0xDFC00000)
+ return (void *) -ENOMEM;
+ addr = (void *) region->end;
+ }
+
+ /* Map anonymous memory */
+ if (flags & MAP_ANONYMOUS) {
+ region = vm_create_region(addr, len, prot, flags, 0, NULL);
+ goto end;
+ }
+
+ /* Map a file */
+ if (fildes < 0 || fildes >= NFILES)
+ return (void *) -EBADF;
+ File *file = get_file_by_fd(fildes);
+ if (!file)
+ return (void *) -EBADF;
+ region = vm_create_region(addr, len, prot, flags, off, file);
+end:
+ if (!region)
+ return (void *) -ENOMEM;
+ void *start = (void *) region->start;
+ put(region);
+ return start;
+}