$NetBSD: patch-cg,v 1.3 2009/01/19 22:35:53 kefren Exp $
--- mono/utils/mono-mmap.c.orig	2009-01-19 10:32:55.000000000 +0200
+++ mono/utils/mono-mmap.c	2009-01-19 18:29:41.000000000 +0200
@@ -7,6 +7,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+#ifdef __NetBSD__
+#include <sys/shm.h>
+#endif
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
@@ -402,7 +405,11 @@
 	const char *name;
 	int i = 0;
 	int curpid = getpid ();
+#ifdef __NetBSD__
+	GDir *dir = g_dir_open ("/tmp/", 0, NULL);
+#else
 	GDir *dir = g_dir_open ("/dev/shm/", 0, NULL);
+#endif
 	if (!dir)
 		return mono_shared_area_instances_slow (array, count, cleanup);
 	while ((name = g_dir_read_name (dir))) {
@@ -421,8 +428,13 @@
 		}
 		if (curpid != pid && kill (pid, SIGCONT) == -1 && errno == ESRCH) {
 			char buf [128];
+#ifdef __NetBSD__
+			g_snprintf (buf, sizeof (buf), "/tmp/mono.%d", pid);
+			unlink (buf);
+#else
 			g_snprintf (buf, sizeof (buf), "/mono.%d", pid);
 			shm_unlink (buf);
+#endif
 		}
 	}
 	g_dir_close (dir);
@@ -439,10 +451,23 @@
 	char buf [128];
 	void *res;
 	SAreaHeader *header;
+#ifdef __NetBSD__
+	key_t skey;
+	int shms;
+#endif
 
 	/* perform cleanup of segments left over from dead processes */
 	mono_shared_area_instances_helper (NULL, 0, TRUE);
+#ifdef __NetBSD__
+	g_snprintf(buf, sizeof (buf), "/tmp/mono.%d", pid);
 
+	fd = open(buf, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP);
+	if (fd == -1 && errno == EEXIST) {
+		/* leftover */
+		unlink(buf);
+		fd = open(buf, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP);
+	}
+#else
 	g_snprintf (buf, sizeof (buf), "/mono.%d", pid);
 
 	fd = shm_open (buf, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP);
@@ -451,11 +476,21 @@
 		shm_unlink (buf);
 		fd = shm_open (buf, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP);
 	}
+#endif
 	/* in case of failure we try to return a memory area anyway,
 	 * even if it means the data can't be read by other processes
 	 */
 	if (fd == -1)
 		return malloc_shared_area (pid);
+#ifdef __NetBSD__
+	if ((skey = ftok(buf, 'M')) == ((key_t)-1) ||
+	    (shms = shmget(skey, size, IPC_CREAT)) == -1 ||
+	    (res = shmat(shms, NULL, 0)) == ((void*)-1)) {
+		close(fd);
+		unlink(buf);
+		return malloc_shared_area(pid);
+	}
+#else
 	if (ftruncate (fd, size) != 0) {
 		shm_unlink (buf);
 		close (fd);
@@ -466,6 +501,7 @@
 		close (fd);
 		return malloc_shared_area (pid);
 	}
+#endif
 	/* we don't need the file descriptor anymore */
 	close (fd);
 	header = res;
@@ -482,8 +518,18 @@
 mono_shared_area_remove (void)
 {
 	char buf [128];
+#ifdef __NetBSD__
+	key_t skey;
+	int shms;
+	struct shmid_ds shmds;
+	g_snprintf(buf, sizeof (buf), "/tmp/mono.%d", getpid());
+	if ((skey = ftok(buf, 'M')) != ((key_t)-1) &&
+	    (shms = shmget(skey, mono_pagesize(), IPC_CREAT)) != -1)
+		shmctl(shms, IPC_RMID, &shmds);
+#else
 	g_snprintf (buf, sizeof (buf), "/mono.%d", getpid ());
 	shm_unlink (buf);
+#endif
 	if (malloced_shared_area)
 		g_free (malloced_shared_area);
 }
@@ -497,6 +543,22 @@
 	char buf [128];
 	void *res;
 
+#ifdef __NetBSD__
+	key_t skey;
+	int shms;
+
+	g_snprintf (buf, sizeof (buf), "/tmp/mono.%d", GPOINTER_TO_INT (pid));
+
+	fd = open(buf, O_RDONLY, S_IRUSR|S_IRGRP);
+	if (fd == -1)
+		return NULL;
+	if ((skey = ftok(buf, 'M')) != ((key_t)-1) ||
+	    (shms = shmget(skey, mono_pagesize(), IPC_CREAT)) != -1 ||
+	    (res = shmat(shms, NULL, 0)) == ((void*)-1)) {
+		close(fd);
+		return NULL;
+	}
+#else
 	g_snprintf (buf, sizeof (buf), "/mono.%d", GPOINTER_TO_INT (pid));
 
 	fd = shm_open (buf, O_RDONLY, S_IRUSR|S_IRGRP);
@@ -507,6 +569,7 @@
 		close (fd);
 		return NULL;
 	}
+#endif
 	/* FIXME: validate the area */
 	/* we don't need the file descriptor anymore */
 	close (fd);
@@ -517,7 +580,11 @@
 mono_shared_area_unload  (void *area)
 {
 	/* FIXME: currently we load only a page */
+#ifdef __NetBSD__
+	shmdt(area);
+#else
 	munmap (area, mono_pagesize ());
+#endif
 }
 
 int
