#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
#include <mono/utils/strenc.h>
#include <mono/io-layer/timefuncs-private.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-membar.h>
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-os-mutex.h>
#include <mono/utils/mono-signal-handler.h>
#include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-once.h>
/* The process' environment strings */
-#if defined(__APPLE__) && !defined (__arm__) && !defined (__aarch64__)
+#if defined(__APPLE__)
+#if defined (TARGET_OSX)
/* Apple defines this in crt_externs.h but doesn't provide that header for
* arm-apple-darwin9. We'll manually define the symbol on Apple as it does
* in fact exist on all implementations (so far)
*/
-char ***_NSGetEnviron(void);
+gchar ***_NSGetEnviron(void);
#define environ (*_NSGetEnviron())
#else
+static char *mono_environ[1] = { NULL };
+#define environ mono_environ
+#endif /* defined (TARGET_OSX) */
+#else
extern char **environ;
#endif
{
gboolean result = FALSE;
-#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(HOST_WATCHOS)
+ result = TRUE; // TODO: Rewrite using sysctl
+#elif defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__)
if (((kill(pid, 0) == 0) || (errno == EPERM)) && pid != 0)
result = TRUE;
#elif defined(__HAIKU__)
WapiStartupInfo *startup,
WapiProcessInformation *process_info)
{
+#if defined (HAVE_FORK) && defined (HAVE_EXECVE)
char *cmd = NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL;
char *dir = NULL, **env_strings = NULL, **argv = NULL;
guint32 i, env_count = 0;
if (newapp != NULL) {
if (appname != NULL) {
- newcmd = utf16_concat (newapp, utf16_space,
+ newcmd = utf16_concat (utf16_quote, newapp, utf16_quote, utf16_space,
appname, utf16_space,
cmdline, NULL);
} else {
- newcmd = utf16_concat (newapp, utf16_space,
+ newcmd = utf16_concat (utf16_quote, newapp, utf16_quote, utf16_space,
cmdline, NULL);
}
mono_process = (struct MonoProcess *) g_malloc0 (sizeof (struct MonoProcess));
mono_process->pid = pid;
mono_process->handle_count = 1;
- if (MONO_SEM_INIT (&mono_process->exit_sem, 0) != 0) {
+ if (mono_os_sem_init (&mono_process->exit_sem, 0) != 0) {
/* If we can't create the exit semaphore, we just don't add anything
* to our list of mono processes. Waiting on the process will return
* immediately. */
process_handle_data->mono_process = mono_process;
- mono_mutex_lock (&mono_processes_mutex);
+ mono_os_mutex_lock (&mono_processes_mutex);
mono_process->next = mono_processes;
mono_processes = mono_process;
- mono_mutex_unlock (&mono_processes_mutex);
+ mono_os_mutex_unlock (&mono_processes_mutex);
}
if (process_info != NULL) {
mono_processes_cleanup ();
return ret;
+#else
+ SetLastError (ERROR_NOT_SUPPORTED);
+ return FALSE;
+#endif // defined (HAVE_FORK) && defined (HAVE_EXECVE)
}
static void
WapiHandle_process process_handle = {0};
_wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS,
- WAPI_HANDLE_CAP_WAIT |
- WAPI_HANDLE_CAP_SPECIAL_WAIT);
+ (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SPECIAL_WAIT));
process_handle.id = pid;
current_process = _wapi_handle_new (WAPI_HANDLE_PROCESS,
&process_handle);
g_assert (current_process);
+
+ mono_os_mutex_init (&mono_processes_mutex);
}
gpointer
return FALSE;
}
pid = process_handle->id;
- proc_name = process_handle->proc_name;
+ proc_name = g_strdup (process_handle->proc_name);
}
#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__HAIKU__)
*/
modules[0] = NULL;
*needed = sizeof(gpointer);
+ g_free (proc_name);
return TRUE;
}
mods = load_modules (fp);
}
for (i = 0; i < count; i++) {
- free_procmodule (g_slist_nth_data (mods, i));
+ free_procmodule ((WapiProcModule *)g_slist_nth_data (mods, i));
}
g_slist_free (mods);
-
+ g_free (proc_name);
+
return TRUE;
}
/* No proc name on OSX < 10.5 nor ppc nor iOS */
memset (buf, '\0', sizeof(buf));
proc_name (pid, buf, sizeof(buf));
- if (strlen (buf) > 0)
+
+ // Fixes proc_name triming values to 15 characters #32539
+ if (strlen (buf) >= MAXCOMLEN - 1) {
+ char path_buf [PROC_PIDPATHINFO_MAXSIZE];
+ char *name_buf;
+ int path_len;
+
+ memset (path_buf, '\0', sizeof(path_buf));
+ path_len = proc_pidpath (pid, path_buf, sizeof(path_buf));
+
+ if (path_len > 0 && path_len < sizeof(path_buf)) {
+ name_buf = path_buf + path_len;
+ for(;name_buf > path_buf; name_buf--) {
+ if (name_buf [0] == '/') {
+ name_buf++;
+ break;
+ }
+ }
+
+ if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0)
+ ret = g_strdup (name_buf);
+ }
+ }
+
+ if (ret == NULL && strlen (buf) > 0)
ret = g_strdup (buf);
#else
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
return 0;
}
+static guint32
+get_module_filename (gpointer process, gpointer module,
+ gunichar2 *basename, guint32 size)
+{
+ int pid, len;
+ gsize bytes;
+ char *path;
+ gunichar2 *proc_path;
+
+ size *= sizeof (gunichar2); /* adjust for unicode characters */
+
+ if (basename == NULL || size == 0)
+ return 0;
+
+ pid = GetProcessId (process);
+
+ path = wapi_process_get_path (pid);
+ if (path == NULL)
+ return 0;
+
+ proc_path = mono_unicode_from_external (path, &bytes);
+ g_free (path);
+
+ if (proc_path == NULL)
+ return 0;
+
+ len = (bytes / 2);
+
+ /* Add the terminator */
+ bytes += 2;
+
+ if (size < bytes) {
+ DEBUG ("%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
+
+ memcpy (basename, proc_path, size);
+ } else {
+ DEBUG ("%s: Size %d larger than needed (%ld)",
+ __func__, size, bytes);
+
+ memcpy (basename, proc_path, bytes);
+ }
+
+ g_free (proc_path);
+
+ return len;
+}
+
guint32
GetModuleBaseName (gpointer process, gpointer module,
gunichar2 *basename, guint32 size)
GetModuleFileNameEx (gpointer process, gpointer module,
gunichar2 *filename, guint32 size)
{
- return get_module_name (process, module, filename, size, FALSE);
+ return get_module_filename (process, module, filename, size);
}
gboolean
gboolean
TerminateProcess (gpointer process, gint32 exitCode)
{
+#if defined(HAVE_KILL)
WapiHandle_process *process_handle;
int signo;
int ret;
}
return (ret == 0);
+#else
+ g_error ("kill() is not supported by this platform");
+ return FALSE;
+#endif
}
guint32
if (mp->pid == 0 && mp->handle) {
/* This process has exited and we need to remove the artifical ref
* on the handle */
- mono_mutex_lock (&mono_processes_mutex);
+ mono_os_mutex_lock (&mono_processes_mutex);
unref_handle = mp->handle;
mp->handle = NULL;
- mono_mutex_unlock (&mono_processes_mutex);
+ mono_os_mutex_unlock (&mono_processes_mutex);
if (unref_handle)
_wapi_handle_unref (unref_handle);
}
* asynchronously. The handler requires that the mono_processes list
* remain valid.
*/
- mono_mutex_lock (&mono_processes_mutex);
+ mono_os_mutex_lock (&mono_processes_mutex);
mp = mono_processes;
while (mp) {
* they have the 'finished' flag set, which means the sigchld handler is done
* accessing them.
*/
- mp = l->data;
- MONO_SEM_DESTROY (&mp->exit_sem);
+ mp = (MonoProcess *)l->data;
+ mono_os_sem_destroy (&mp->exit_sem);
g_free (mp);
}
g_slist_free (finished);
- mono_mutex_unlock (&mono_processes_mutex);
+ mono_os_mutex_unlock (&mono_processes_mutex);
DEBUG ("%s done", __func__);
if (p) {
p->pid = 0; /* this pid doesn't exist anymore, clear it */
p->status = status;
- MONO_SEM_POST (&p->exit_sem);
+ mono_os_sem_post (&p->exit_sem);
mono_memory_barrier ();
/* Mark this as freeable, the pointer becomes invalid afterwards */
p->freeable = TRUE;
if (timeout != INFINITE) {
DEBUG ("%s (%p, %u): waiting on semaphore for %li ms...",
__func__, handle, timeout, (timeout - (now - start)));
-
- ret = MONO_SEM_TIMEDWAIT_ALERTABLE (&mp->exit_sem, (timeout - (now - start)), alertable);
+ ret = mono_os_sem_timedwait (&mp->exit_sem, (timeout - (now - start)), alertable ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
} else {
DEBUG ("%s (%p, %u): waiting on semaphore forever...",
__func__, handle, timeout);
- ret = MONO_SEM_WAIT_ALERTABLE (&mp->exit_sem, alertable);
+ ret = mono_os_sem_wait (&mp->exit_sem, alertable ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
}
if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) {
if (ret == 0) {
/* Success, process has exited */
- MONO_SEM_POST (&mp->exit_sem);
+ mono_os_sem_post (&mp->exit_sem);
break;
}