[xbuild] ImportCollections.TryGetImport and other fixes
[mono.git] / mono / io-layer / processes.c
index b2777006bd6d84411e8d966dc60a0f0d2fd980d1..d0501a7dbe0f9638683bdc972f12147a0acaa75f 100644 (file)
@@ -1594,7 +1594,8 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 #if defined(__OpenBSD__)
                pids [j++] = result [i].p_pid;
 #else
-               pids [j++] = result [i].kp_proc.p_pid;
+               if (result[i].kp_proc.p_pid > 0) /* Pid 0 not supported */
+                       pids [j++] = result [i].kp_proc.p_pid;
 #endif
        }
        free (result);
@@ -1624,8 +1625,7 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 #else
 gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
 {
-       GArray *processes = g_array_new (FALSE, FALSE, sizeof(pid_t));
-       guint32 fit, i, j;
+       guint32 fit, i;
        DIR *dir;
        struct dirent *entry;
        
@@ -1635,29 +1635,22 @@ gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
        if (dir == NULL) {
                return(FALSE);
        }
-       while((entry = readdir (dir)) != NULL) {
-               if (isdigit (entry->d_name[0])) {
-                       char *endptr;
-                       pid_t pid = (pid_t)strtol (entry->d_name, &endptr, 10);
 
-                       if (*endptr == '\0') {
-                               /* Name was entirely numeric, so was a
-                                * process ID
-                                */
-                               g_array_append_val (processes, pid);
-                       }
-               }
-       }
-       closedir (dir);
+       i = 0;
+       fit = len / sizeof (guint32);
+       while(i < fit && (entry = readdir (dir)) != NULL) {
+               pid_t pid;
+               char *endptr;
 
-       fit=len/sizeof(guint32);
-       for (i = 0, j = 0; j < fit && i < processes->len; i++) {
-               pids[j++] = g_array_index (processes, pid_t, i);
-       }
+               if (!isdigit (entry->d_name[0]))
+                       continue;
 
-       g_array_free (processes, TRUE);
-       
-       *needed = j * sizeof(guint32);
+               pid = (pid_t) strtol (entry->d_name, &endptr, 10);
+               if (*endptr == '\0')
+                       pids [i++] = (guint32) pid;
+       }
+       closedir (dir);
+       *needed = i * sizeof(guint32);
        
        return(TRUE);
 }
@@ -1690,6 +1683,16 @@ static gboolean process_open_compare (gpointer handle, gpointer user_data)
        }
 }
 
+gboolean CloseProcess(gpointer handle)
+{
+       if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+               /* This is a pseudo handle */
+               return(TRUE);
+       }
+
+       return CloseHandle (handle);
+}
+
 gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid)
 {
        /* Find the process handle that corresponds to pid */
@@ -1701,13 +1704,12 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_
        g_message ("%s: looking for process %d", __func__, pid);
 #endif
 
-       if (_wapi_shm_enabled ())
-               handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
-                                             process_open_compare,
-                                             GUINT_TO_POINTER (pid), NULL, TRUE);
+       handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
+                                     process_open_compare,
+                                     GUINT_TO_POINTER (pid), NULL, TRUE);
        if (handle == 0) {
 #if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
-               if ((kill(pid, 0) == 0) || (errno == EPERM)) {
+               if (((kill(pid, 0) == 0) || (errno == EPERM)) && pid != 0) {
 #elif defined(__HAIKU__)
                team_info teamInfo;
                if (get_team_info ((team_id)pid, &teamInfo) == B_OK) {
@@ -1739,6 +1741,7 @@ gboolean GetExitCodeProcess (gpointer process, guint32 *code)
 {
        struct _WapiHandle_process *process_handle;
        gboolean ok;
+       guint32 pid = -1;
        
        mono_once (&process_current_once, process_set_current);
 
@@ -1746,13 +1749,27 @@ gboolean GetExitCodeProcess (gpointer process, guint32 *code)
                return(FALSE);
        }
        
+       pid = GPOINTER_TO_UINT (process) - _WAPI_PROCESS_UNHANDLED;
        if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
                /* This is a pseudo handle, so we don't know what the
-                * exit code was
+                * exit code was, but we can check whether it's alive or not
                 */
-               return(FALSE);
+#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__)
+               if ((kill(pid, 0) == 0) || (errno == EPERM)) {
+#elif defined(__HAIKU__)
+               team_info teamInfo;
+               if (get_team_info ((team_id)pid, &teamInfo) == B_OK) {
+#else
+               gchar *dir = g_strdup_printf ("/proc/%d", pid);
+               if (!access (dir, F_OK)) {
+#endif
+                       *code = STILL_ACTIVE;
+                       return TRUE;
+               } else {
+                       return FALSE;
+               }
        }
-       
+
        ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
                                (gpointer *)&process_handle);
        if(ok==FALSE) {
@@ -2206,7 +2223,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
 {
        struct _WapiHandle_process *process_handle;
        gboolean ok;
-#if !defined(__OpenBSD__)
+#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX)
        FILE *fp;
 #endif
        GSList *mods = NULL;
@@ -2294,11 +2311,19 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules,
 
 static gchar *get_process_name_from_proc (pid_t pid)
 {
-#if !defined(__OpenBSD__)
+#ifdef __OpenBSD__
+       int mib [6];
+       size_t size;
+       struct kinfo_proc2 *pi;
+#elif defined(PLATFORM_MACOSX)
+       size_t size;
+       struct kinfo_proc *pi;
+       int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
+#else
        FILE *fp;
        gchar *filename = NULL;
-       gchar buf[256];
 #endif
+       gchar buf[256];
        gchar *ret = NULL;
 
 #if defined(PLATFORM_SOLARIS)
@@ -2316,12 +2341,34 @@ static gchar *get_process_name_from_proc (pid_t pid)
        }
        g_free (filename);
 #elif defined(PLATFORM_MACOSX)
+#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) && !defined (__mono_ppc__) && !defined(__arm__)
+       /* No proc name on OSX < 10.5 nor ppc nor iOS */
        memset (buf, '\0', sizeof(buf));
-#  if !defined (__mono_ppc__) && !defined(__arm__)
        proc_name (pid, buf, sizeof(buf));
-#  endif
        if (strlen (buf) > 0)
                ret = g_strdup (buf);
+#else
+       if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
+               return(ret);
+
+       if ((pi = malloc(size)) == NULL)
+               return(ret);
+
+       if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
+               if (errno == ENOMEM) {
+                       free(pi);
+#ifdef DEBUG
+                       g_message ("%s: Didn't allocate enough memory for kproc info", __func__);
+#endif
+               }
+               return(ret);
+       }
+
+       if (strlen (pi->kp_proc.p_comm) > 0)
+               ret = g_strdup (pi->kp_proc.p_comm);
+
+       free(pi);
+#endif
 #elif defined(__OpenBSD__)
        int mib [6];
        size_t size;
@@ -2410,11 +2457,7 @@ retry:
        g_free (filename);
 #endif
 
-       if (ret != NULL) {
-               return(ret);
-       }
-
-       return(NULL);
+       return ret;
 }
 
 static guint32 get_module_name (gpointer process, gpointer module,
@@ -2428,7 +2471,7 @@ static guint32 get_module_name (gpointer process, gpointer module,
        gchar *procname_ext = NULL;
        glong len;
        gsize bytes;
-#if !defined(__OpenBSD__)
+#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX)
        FILE *fp;
 #endif
        GSList *mods = NULL;
@@ -2582,7 +2625,7 @@ gboolean GetModuleInformation (gpointer process, gpointer module,
        struct _WapiHandle_process *process_handle;
        gboolean ok;
        pid_t pid;
-#if !defined(__OpenBSD__)
+#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX)
        FILE *fp;
 #endif
        GSList *mods = NULL;