changeset 39232:b726e355a7d6

vma-iter: Add support for Minix 3. * lib/vma-iter.h (VMA_ITERATE_SUPPORTED): Define on Minix. * lib/vma-iter.c: On Minix, read /proc/<pid>/map.
author Bruno Haible <bruno@clisp.org>
date Tue, 30 Jan 2018 09:02:46 +0100
parents 05af34a75041
children 492d30539cc8
files ChangeLog lib/vma-iter.c lib/vma-iter.h
diffstat 3 files changed, 91 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jan 27 10:57:59 2018 +0100
+++ b/ChangeLog	Tue Jan 30 09:02:46 2018 +0100
@@ -1,3 +1,9 @@
+2018-01-30  Bruno Haible  <bruno@clisp.org>
+
+	vma-iter: Add support for Minix 3.
+	* lib/vma-iter.h (VMA_ITERATE_SUPPORTED): Define on Minix.
+	* lib/vma-iter.c: On Minix, read /proc/<pid>/map.
+
 2018-01-27  Bruno Haible  <bruno@clisp.org>
 
 	Fix malfunction of socket functions on HP-UX in 64-bit mode.
--- a/lib/vma-iter.c	Sat Jan 27 10:57:59 2018 +0100
+++ b/lib/vma-iter.c	Tue Jan 30 09:02:46 2018 +0100
@@ -38,10 +38,13 @@
 # include <limits.h> /* PATH_MAX */
 #endif
 
-#if defined __linux__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ /* || defined __CYGWIN__ */
+#if defined __linux__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __minix /* || defined __CYGWIN__ */
 # include <sys/types.h>
 # include <sys/mman.h> /* mmap, munmap */
 #endif
+#if defined __minix
+# include <string.h> /* memcpy */
+#endif
 
 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ /* FreeBSD, GNU/kFreeBSD */
 # include <sys/types.h>
@@ -103,7 +106,7 @@
 
 /* Support for reading text files in the /proc file system.  */
 
-#if defined __linux__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ /* || defined __CYGWIN__ */
+#if defined __linux__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __minix /* || defined __CYGWIN__ */
 
 /* Buffered read-only streams.
    We cannot use <stdio.h> here, because fopen() calls malloc(), and a malloc()
@@ -493,6 +496,84 @@
   return -1;
 }
 
+#elif defined __minix
+
+static int
+vma_iterate_proc (vma_iterate_callback_fn callback, void *data)
+{
+  char fnamebuf[6+10+4+1];
+  char *fname;
+  struct rofile rof;
+
+  /* Construct fname = sprintf (fnamebuf+i, "/proc/%u/map", getpid ()).  */
+  fname = fnamebuf + sizeof (fnamebuf) - (4 + 1);
+  memcpy (fname, "/map", 4 + 1);
+  {
+    unsigned int value = getpid ();
+    do
+      *--fname = (value % 10) + '0';
+    while ((value = value / 10) > 0);
+  }
+  fname -= 6;
+  memcpy (fname, "/proc/", 6);
+
+  /* Open the current process' maps file.  It describes one VMA per line.  */
+  if (rof_open (&rof, fname) >= 0)
+    {
+      unsigned long auxmap_start = rof.auxmap_start;
+      unsigned long auxmap_end = rof.auxmap_end;
+
+      for (;;)
+        {
+          unsigned long start, end;
+          unsigned int flags;
+          int c;
+
+          /* Parse one line.  First start and end.  */
+          if (!(rof_scanf_lx (&rof, &start) >= 0
+                && rof_getchar (&rof) == '-'
+                && rof_scanf_lx (&rof, &end) >= 0))
+            break;
+          /* Then the flags.  */
+          do
+            c = rof_getchar (&rof);
+          while (c == ' ');
+          flags = 0;
+          if (c == 'r')
+            flags |= VMA_PROT_READ;
+          c = rof_getchar (&rof);
+          if (c == 'w')
+            flags |= VMA_PROT_WRITE;
+          c = rof_getchar (&rof);
+          if (c == 'x')
+            flags |= VMA_PROT_EXECUTE;
+          while (c = rof_getchar (&rof), c != -1 && c != '\n')
+            ;
+
+          if (start <= auxmap_start && auxmap_end - 1 <= end - 1)
+            {
+              /* Consider [start,end-1] \ [auxmap_start,auxmap_end-1]
+                 = [start,auxmap_start-1] u [auxmap_end,end-1].  */
+              if (start < auxmap_start)
+                if (callback (data, start, auxmap_start, flags))
+                  break;
+              if (auxmap_end - 1 < end - 1)
+                if (callback (data, auxmap_end, end, flags))
+                  break;
+            }
+          else
+            {
+              if (callback (data, start, end, flags))
+                break;
+            }
+        }
+      rof_close (&rof);
+      return 0;
+    }
+
+  return -1;
+}
+
 #else
 
 static inline int
@@ -779,7 +860,7 @@
 int
 vma_iterate (vma_iterate_callback_fn callback, void *data)
 {
-#if defined __linux__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ /* || defined __CYGWIN__ */
+#if defined __linux__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __minix /* || defined __CYGWIN__ */
 
 # if defined __FreeBSD__
   /* On FreeBSD with procfs (but not GNU/kFreeBSD, which uses linprocfs), the
--- a/lib/vma-iter.h	Sat Jan 27 10:57:59 2018 +0100
+++ b/lib/vma-iter.h	Tue Jan 30 09:02:46 2018 +0100
@@ -52,7 +52,7 @@
    this platform.
    Note that even when this macro is defined, vma_iterate() may still fail to
    find any virtual memory area, for example if /proc is not mounted.  */
-#if defined __linux__ || defined __GNU__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __sgi || defined __osf__ || defined __sun || HAVE_PSTAT_GETPROCVM || (defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __WIN32__) || defined __CYGWIN__ || defined __BEOS__ || defined __HAIKU__ || HAVE_MQUERY
+#if defined __linux__ || defined __GNU__ || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __sgi || defined __osf__ || defined __sun || HAVE_PSTAT_GETPROCVM || (defined __APPLE__ && defined __MACH__) || (defined _WIN32 || defined __WIN32__) || defined __CYGWIN__ || defined __BEOS__ || defined __HAIKU__ || defined __minix || HAVE_MQUERY
 # define VMA_ITERATE_SUPPORTED 1
 #endif