openbsd-ports/lang/mono/patches/patch-mono_io-layer_processes_c
robert 281e83e581 Fix kinfo_proc2 code and add support for more mono stuff using sysctl to
get process informations. Remove the mkbundle.cs patch and replace it
with one that uses configure.in so the libgc dependency ends up in the
pkg-config file. Move disabled features to configure.in from our Makefile
2010-04-08 12:12:33 +00:00

317 lines
8.0 KiB
Plaintext

$OpenBSD: patch-mono_io-layer_processes_c,v 1.1 2010/04/08 12:12:33 robert Exp $
--- mono/io-layer/processes.c.orig Thu Apr 8 12:26:28 2010
+++ mono/io-layer/processes.c Thu Apr 8 12:24:52 2010
@@ -35,10 +35,12 @@
#include <sys/resource.h>
#endif
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
#include <sys/proc.h>
#include <sys/sysctl.h>
-#include <sys/utsname.h>
+# if !defined(__OpenBSD__)
+# include <sys/utsname.h>
+# endif
#endif
#ifdef PLATFORM_SOLARIS
@@ -78,7 +80,9 @@ extern char **environ;
#undef DEBUG
static guint32 process_wait (gpointer handle, guint32 timeout);
+#if !defined(__OpenBSD__)
FILE *open_process_map (int pid, const char *mode);
+#endif
struct _WapiHandleOps _wapi_process_ops = {
NULL, /* close_shared */
@@ -1511,16 +1515,27 @@ static gboolean process_enum (gpointer handle, gpointe
}
#endif /* UNUSED_CODE */
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
{
guint32 count, fit, i, j;
gint32 err;
gboolean done;
+ size_t proclength, size;
+#if defined(__OpenBSD__)
+ struct kinfo_proc2 *result;
+ int name[6];
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC2;
+ name[2] = KERN_PROC_ALL;
+ name[3] = 0;
+ name[4] = sizeof(struct kinfo_proc2);
+ name[5] = 0;
+#else
struct kinfo_proc *result;
- size_t proclength;
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
+#endif
mono_once (&process_current_once, process_set_current);
@@ -1529,15 +1544,24 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, gu
do {
proclength = 0;
- err = sysctl ((int *)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &proclength, NULL, 0);
+#if defined(__OpenBSD__)
+ size = (sizeof(name) / sizeof(*name));
+#else
+ size = (sizeof(name) / sizeof(*name)) - 1;
+#endif
+ err = sysctl ((int *)name, size, NULL, &proclength, NULL, 0);
if (err == 0) {
result = malloc (proclength);
if (result == NULL)
return FALSE;
-
- err = sysctl ((int *) name, (sizeof(name) / sizeof(*name)) - 1, result, &proclength, NULL, 0);
+
+#if defined(__OpenBSD__)
+ name[5] = (int)(proclength / sizeof(struct kinfo_proc2));
+#endif
+ err = sysctl ((int *) name, size, result, &proclength, NULL, 0);
+
if (err == 0)
done = TRUE;
else
@@ -1552,11 +1576,19 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, gu
}
return(FALSE);
}
-
+
+#if defined(__OpenBSD__)
+ count = proclength / sizeof(struct kinfo_proc2);
+#else
count = proclength / sizeof(struct kinfo_proc);
+#endif
fit = len / sizeof(guint32);
for (i = 0, j = 0; j< fit && i < count; i++) {
+#if defined(__OpenBSD__)
+ pids [j++] = result [i].p_pid;
+#else
pids [j++] = result [i].kp_proc.p_pid;
+#endif
}
free (result);
result = NULL;
@@ -1648,8 +1680,12 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED
process_open_compare,
GUINT_TO_POINTER (pid), NULL, TRUE);
if (handle == 0) {
+#if defined(__OpenBSD__)
+ if ((kill(pid, 0) == 0) || (errno == EPERM)) {
+#else
gchar *dir = g_strdup_printf ("/proc/%d", pid);
if (!access (dir, F_OK)) {
+#endif
/* Return a pseudo handle for processes we
* don't have handles for
*/
@@ -1862,6 +1898,67 @@ static GSList *load_modules (void)
return(ret);
}
+#elif defined(__OpenBSD__)
+#include <link.h>
+static int load_modules_callback (struct dl_phdr_info *info, size_t size, void *ptr)
+{
+ if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
+ + sizeof (info->dlpi_phnum))
+ return (-1);
+
+ struct dl_phdr_info *cpy = calloc(1, sizeof(struct dl_phdr_info));
+ if (!cpy)
+ return (-1);
+
+ memcpy(cpy, info, sizeof(*info));
+
+ g_ptr_array_add ((GPtrArray *)ptr, cpy);
+
+ return (0);
+}
+
+static GSList *load_modules (void)
+{
+ GSList *ret = NULL;
+ WapiProcModule *mod;
+ GPtrArray *dlarray = g_ptr_array_new();
+ int i;
+
+ if (dl_iterate_phdr(load_modules_callback, dlarray) < 0)
+ return (ret);
+
+ for (i = 0; i < dlarray->len; i++) {
+ struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);
+
+ mod = g_new0 (WapiProcModule, 1);
+ mod->address_start = (gpointer)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
+ mod->address_end = (gpointer)(info->dlpi_addr +
+ info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
+ mod->perms = g_strdup ("r--p");
+ mod->address_offset = 0;
+ mod->inode = (ino_t) i;
+ mod->filename = g_strdup (info->dlpi_name);
+
+#ifdef DEBUG
+ g_message ("%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
+ mod->inode, mod->filename, mod->address_start, mod->address_end);
+#endif
+
+ free(info);
+
+ if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
+ ret = g_slist_prepend (ret, mod);
+ } else {
+ free_procmodule (mod);
+ }
+ }
+
+ g_ptr_array_free (dlarray, TRUE);
+
+ ret = g_slist_reverse (ret);
+
+ return(ret);
+}
#else
static GSList *load_modules (FILE *fp)
{
@@ -2012,6 +2109,7 @@ static gboolean match_procname_to_modulename (gchar *p
return result;
}
+#if !defined(__OpenBSD__)
FILE *open_process_map (int pid, const char *mode)
{
FILE *fp = NULL;
@@ -2031,13 +2129,16 @@ FILE *open_process_map (int pid, const char *mode)
return fp;
}
+#endif
gboolean EnumProcessModules (gpointer process, gpointer *modules,
guint32 size, guint32 *needed)
{
struct _WapiHandle_process *process_handle;
gboolean ok;
+#if !defined(__OpenBSD__)
FILE *fp;
+#endif
GSList *mods = NULL;
WapiProcModule *module;
guint32 count, avail = size / sizeof(gpointer);
@@ -2075,7 +2176,7 @@ gboolean EnumProcessModules (gpointer process, gpointe
proc_name = process_handle->proc_name;
}
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
{
mods = load_modules ();
#else
@@ -2123,10 +2224,12 @@ gboolean EnumProcessModules (gpointer process, gpointe
static gchar *get_process_name_from_proc (pid_t pid)
{
+#if !defined(__OpenBSD__)
+ FILE *fp;
gchar *filename = NULL;
- gchar *ret = NULL;
gchar buf[256];
- FILE *fp;
+#endif
+ gchar *ret = NULL;
#if defined(PLATFORM_SOLARIS)
filename = g_strdup_printf ("/proc/%d/psinfo", pid);
@@ -2149,6 +2252,40 @@ static gchar *get_process_name_from_proc (pid_t pid)
# endif
if (strlen (buf) > 0)
ret = g_strdup (buf);
+#elif defined(__OpenBSD__)
+ int mib [6];
+ size_t size;
+ struct kinfo_proc2 *pi;
+
+ mib [0] = CTL_KERN;
+ mib [1] = KERN_PROC2;
+ mib [2] = KERN_PROC_PID;
+ mib [3] = pid;
+ mib [4] = sizeof(struct kinfo_proc2);
+ mib [5] = 0;
+
+retry:
+ if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0)
+ return(ret);
+
+ if ((pi = malloc(size)) == NULL)
+ return(ret);
+
+ mib[5] = (int)(size / sizeof(struct kinfo_proc2));
+
+ if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) ||
+ (size != sizeof (struct kinfo_proc2))) {
+ if (errno == ENOMEM) {
+ free(pi);
+ goto retry;
+ }
+ return(ret);
+ }
+
+ if (strlen (pi->p_comm) > 0)
+ ret = g_strdup (pi->p_comm);
+
+ free(pi);
#else
memset (buf, '\0', sizeof(buf));
filename = g_strdup_printf ("/proc/%d/exe", pid);
@@ -2214,7 +2351,9 @@ static guint32 get_module_name (gpointer process, gpoi
gchar *procname_ext = NULL;
glong len;
gsize bytes;
+#if !defined(__OpenBSD__)
FILE *fp;
+#endif
GSList *mods = NULL;
WapiProcModule *found_module;
guint32 count;
@@ -2254,7 +2393,7 @@ static guint32 get_module_name (gpointer process, gpoi
}
/* Look up the address in /proc/<pid>/maps */
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
{
mods = load_modules ();
#else
@@ -2366,7 +2505,9 @@ gboolean GetModuleInformation (gpointer process, gpoin
struct _WapiHandle_process *process_handle;
gboolean ok;
pid_t pid;
+#if !defined(__OpenBSD__)
FILE *fp;
+#endif
GSList *mods = NULL;
WapiProcModule *found_module;
guint32 count;
@@ -2404,7 +2545,7 @@ gboolean GetModuleInformation (gpointer process, gpoin
proc_name = g_strdup (process_handle->proc_name);
}
-#ifdef PLATFORM_MACOSX
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
{
mods = load_modules ();
#else