BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 665af0a43af0d406733bda816ca1a7b2f9184319 / memory / mmap.c

// Related

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;
+}