2009-12-02 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Wed, 2 Dec 2009 18:27:15 +0000 (18:27 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Wed, 2 Dec 2009 18:27:15 +0000 (18:27 -0000)
* processes.c (EnumProcesses): Add support for OSX, patch from Tom
Philpot <tom.philpot@logos.com>

svn path=/trunk/mono/; revision=147481

mono/io-layer/ChangeLog
mono/io-layer/processes.c

index f478c815fdcc195a58fac28a3664fc75d885c5d0..ad510d5c01e7fc985f0f479dba146a7d1dac02c9 100644 (file)
@@ -1,3 +1,8 @@
+2009-12-02  Miguel de Icaza  <miguel@novell.com>
+
+       * processes.c (EnumProcesses): Add support for OSX, patch from Tom
+       Philpot <tom.philpot@logos.com>
+
 2009-11-30  Carlos Alberto Cortez <calberto.cortez@gmail.com>
 
        * io.cs: In CopyFile check if the destination already exists before
index 1c1520b962d94bf0600a1fec39048beda42a9970..d21d39307dfadbee66bc0e4d52957b848a52c010 100644 (file)
 #include <sys/resource.h>
 #endif
 
+#ifdef PLATFORM_MACOSX
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+#endif
+
 #ifdef PLATFORM_SOLARIS
 /* procfs.h cannot be included if this define is set, but it seems to work fine if it is undefined */
 #if _FILE_OFFSET_BITS == 64
@@ -408,7 +414,6 @@ utf16_concat (const gunichar2 *first, ...)
 }
 
 #ifdef PLATFORM_MACOSX
-#include <sys/utsname.h>
 
 /* 0 = no detection; -1 = not 10.5 or higher;  1 = 10.5 or higher */
 static int osx_10_5_or_higher;
@@ -1489,6 +1494,60 @@ static gboolean process_enum (gpointer handle, gpointer user_data)
 }
 #endif /* UNUSED_CODE */
 
+#ifdef PLATFORM_MACOSX
+
+gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
+{
+       guint32 count, fit, i, j;
+       gint32 err;
+       gboolean done;
+       struct kinfo_proc *result;
+       size_t proclength;
+       static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
+       
+       mono_once (&process_current_once, process_set_current);
+       
+       result = NULL;
+       done = FALSE;
+       
+       do {
+               proclength = 0;
+               err = sysctl ((int *)name, (sizeof(name) / sizeof(*name)) - 1, 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 (err == 0) 
+                               done = TRUE;
+                       else
+                               free (result);
+               }
+       } while (err == 0 && !done);
+       
+       if (err != 0) {
+               if (result != NULL) {
+                       free (result);
+                       result = NULL;
+               }
+               return(FALSE);
+       }       
+       
+       count = proclength / sizeof(struct kinfo_proc);
+       fit = len / sizeof(guint32);
+       for (i = 0, j = 0; j< fit && i < count; i++) {
+               pids [j++] = result [i].kp_proc.p_pid;
+       }
+       free (result);
+       result = NULL;
+       *needed = j * sizeof(guint32);
+       
+       return(TRUE);
+}
+#else
 gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 {
        GArray *processes = g_array_new (FALSE, FALSE, sizeof(pid_t));
@@ -1528,6 +1587,7 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
        
        return(TRUE);
 }
+#endif
 
 static gboolean process_open_compare (gpointer handle, gpointer user_data)
 {
@@ -2050,9 +2110,28 @@ static gchar *get_process_name_from_proc (pid_t pid)
        gchar *ret = NULL;
        gchar buf[256];
        FILE *fp;
-       
+
+#if defined(PLATFORM_SOLARIS)
+       filename = g_strdup_printf ("/proc/%d/psinfo", pid);
+       if ((fp = fopen (filename, "r")) != NULL) {
+               struct psinfo info;
+               int nread;
+
+               nread = fread (&info, sizeof (info), 1, fp);
+               if (nread == 1) {
+                       ret = g_strdup (info.pr_fname);
+               }
+
+               fclose (fp);
+       }
+       g_free (filename);
+#elif defined(PLATFORM_MACOSX)
+       memset (buf, '\0', sizeof(buf));
+       proc_name (pid, buf, sizeof(buf));
+       if (strlen (buf) > 0)
+               ret = g_strdup (buf);
+#else
        memset (buf, '\0', sizeof(buf));
-       
        filename = g_strdup_printf ("/proc/%d/exe", pid);
        if (readlink (filename, buf, 255) > 0) {
                ret = g_strdup (buf);
@@ -2062,7 +2141,7 @@ static gchar *get_process_name_from_proc (pid_t pid)
        if (ret != NULL) {
                return(ret);
        }
-       
+
        filename = g_strdup_printf ("/proc/%d/cmdline", pid);
        if ((fp = fopen (filename, "r")) != NULL) {
                if (fgets (buf, 256, fp) != NULL) {
@@ -2096,25 +2175,6 @@ static gchar *get_process_name_from_proc (pid_t pid)
                fclose (fp);
        }
        g_free (filename);
-
-       if (ret != NULL) {
-               return(ret);
-       }
-
-#ifdef PLATFORM_SOLARIS
-       filename = g_strdup_printf ("/proc/%d/psinfo", pid);
-       if ((fp = fopen (filename, "r")) != NULL) {
-               struct psinfo info;
-               int nread;
-
-               nread = fread (&info, sizeof (info), 1, fp);
-               if (nread == 1) {
-                       ret = g_strdup (info.pr_fname);
-               }
-               
-               fclose (fp);
-       }
-       g_free (filename);
 #endif
 
        if (ret != NULL) {