X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fio-layer%2Fprocesses.c;h=48a9687782942f77254e57fa0b6bed58ea884cbc;hb=8eeb2cef8fb37b7aaeed5fb0c31550a1701f9bdf;hp=ce7aee14c884732d669200fc8bcbc3a2599d718b;hpb=2ffce7f1bf6b6303f6a42d357570d849c3d50476;p=mono.git diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c index ce7aee14c88..48a96877829 100644 --- a/mono/io-layer/processes.c +++ b/mono/io-layer/processes.c @@ -54,12 +54,15 @@ #endif #endif -#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) +#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__) #include #include # if !defined(__OpenBSD__) # include # endif +# if defined(__FreeBSD__) +# include /* struct kinfo_proc */ +# endif #endif #ifdef PLATFORM_SOLARIS @@ -115,7 +118,7 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl static void process_close (gpointer handle, gpointer data); static gboolean is_pid_valid (pid_t pid); -#if !(defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)) +#if !(defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__HAIKU__)) static FILE * open_process_map (int pid, const char *mode); #endif @@ -175,7 +178,9 @@ is_pid_valid (pid_t pid) { gboolean result = FALSE; -#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) +#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__) @@ -549,6 +554,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, 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; @@ -812,11 +818,11 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, 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); } @@ -839,7 +845,6 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } else { if (!is_executable (prog)) { DEBUG ("%s: Executable permisson not set on %s", __func__, prog); - g_free (prog); SetLastError (ERROR_ACCESS_DENIED); goto free_strings; } @@ -1094,6 +1099,10 @@ free_strings: mono_processes_cleanup (); return ret; +#else + SetLastError (ERROR_NOT_SUPPORTED); + return FALSE; +#endif // defined (HAVE_FORK) && defined (HAVE_EXECVE) } static void @@ -1449,7 +1458,7 @@ static GSList *load_modules (void) return(ret); } -#elif defined(__OpenBSD__) +#elif defined(__OpenBSD__) || defined(__FreeBSD__) #include static int load_modules_callback (struct dl_phdr_info *info, size_t size, void *ptr) { @@ -1671,6 +1680,7 @@ static gboolean match_procname_to_modulename (char *procname, char *modulename) if (procname == NULL || modulename == NULL) return (FALSE); + DEBUG ("%s: procname=\"%s\", modulename=\"%s\"", __func__, procname, modulename); pname = mono_path_resolve_symlinks (procname); mname = mono_path_resolve_symlinks (modulename); @@ -1699,10 +1709,11 @@ static gboolean match_procname_to_modulename (char *procname, char *modulename) g_free (pname); g_free (mname); + DEBUG ("%s: result is %d", __func__, result); return result; } -#if !(defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)) +#if !(defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__HAIKU__)) static FILE * open_process_map (int pid, const char *mode) { @@ -1725,11 +1736,13 @@ open_process_map (int pid, const char *mode) } #endif +static char *get_process_name_from_proc (pid_t pid); + gboolean EnumProcessModules (gpointer process, gpointer *modules, guint32 size, guint32 *needed) { WapiHandle_process *process_handle; -#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) +#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) && !defined(__FreeBSD__) FILE *fp; #endif GSList *mods = NULL; @@ -1753,6 +1766,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules, if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { pid = WAPI_HANDLE_TO_PID (process); + proc_name = get_process_name_from_proc (pid); } else { process_handle = lookup_process_handle (process); if (!process_handle) { @@ -1764,7 +1778,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules, proc_name = process_handle->proc_name; } -#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__) +#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__HAIKU__) mods = load_modules (); if (!proc_name) { modules[0] = NULL; @@ -1819,7 +1833,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules, static char * get_process_name_from_proc (pid_t pid) { -#if defined(__OpenBSD__) +#if defined(__OpenBSD__) || defined(__FreeBSD__) int mib [6]; size_t size; struct kinfo_proc *pi; @@ -1855,7 +1869,31 @@ get_process_name_from_proc (pid_t pid) /* 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) @@ -1877,6 +1915,30 @@ get_process_name_from_proc (pid_t pid) free(pi); #endif +#elif defined(__FreeBSD__) + mib [0] = CTL_KERN; + mib [1] = KERN_PROC; + mib [2] = KERN_PROC_PID; + mib [3] = pid; + if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) { + DEBUG ("%s: sysctl() failed: %d", __func__, errno); + return(ret); + } + + if ((pi = malloc(size)) == NULL) + return(ret); + + if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) { + if (errno == ENOMEM) { + free(pi); + DEBUG ("%s: Didn't allocate enough memory for kproc info", __func__); + } + return(ret); + } + + if (strlen (pi->ki_comm) > 0) + ret = g_strdup (pi->ki_comm); + free(pi); #elif defined(__OpenBSD__) mib [0] = CTL_KERN; mib [1] = KERN_PROC; @@ -1886,8 +1948,10 @@ get_process_name_from_proc (pid_t pid) mib [5] = 0; retry: - if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) + if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) { + DEBUG ("%s: sysctl() failed: %d", __func__, errno); return(ret); + } if ((pi = malloc(size)) == NULL) return(ret); @@ -1903,8 +1967,13 @@ retry: return(ret); } +#if defined(__OpenBSD__) if (strlen (pi->p_comm) > 0) ret = g_strdup (pi->p_comm); +#elif defined(__FreeBSD__) + if (strlen (pi->ki_comm) > 0) + ret = g_strdup (pi->ki_comm); +#endif free(pi); #elif defined(__HAIKU__) @@ -2011,7 +2080,7 @@ get_module_name (gpointer process, gpointer module, char *procname_ext = NULL; glong len; gsize bytes; -#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) +#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) && !defined(__FreeBSD__) FILE *fp; #endif GSList *mods = NULL; @@ -2045,7 +2114,7 @@ get_module_name (gpointer process, gpointer module, } /* Look up the address in /proc//maps */ -#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__) +#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__HAIKU__) mods = load_modules (); #else fp = open_process_map (pid, "r"); @@ -2131,6 +2200,44 @@ get_module_name (gpointer process, gpointer module, 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; + + pid = GetProcessId (process); + + path = wapi_process_get_path (pid); + if (path == NULL) + return 0; + + proc_path = mono_unicode_from_external (path, &bytes); + 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); + } + + return len; +} + guint32 GetModuleBaseName (gpointer process, gpointer module, gunichar2 *basename, guint32 size) @@ -2142,7 +2249,7 @@ guint32 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 @@ -2151,7 +2258,7 @@ GetModuleInformation (gpointer process, gpointer module, { WapiHandle_process *process_handle; pid_t pid; -#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) +#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) && !defined(__FreeBSD__) FILE *fp; #endif GSList *mods = NULL; @@ -2182,7 +2289,7 @@ GetModuleInformation (gpointer process, gpointer module, proc_name = g_strdup (process_handle->proc_name); } -#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__) +#if defined(PLATFORM_MACOSX) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) mods = load_modules (); #else /* Look up the address in /proc//maps */ @@ -2275,6 +2382,7 @@ SetProcessWorkingSetSize (gpointer process, size_t min, size_t max) gboolean TerminateProcess (gpointer process, gint32 exitCode) { +#if defined(HAVE_KILL) WapiHandle_process *process_handle; int signo; int ret; @@ -2312,6 +2420,10 @@ TerminateProcess (gpointer process, gint32 exitCode) } return (ret == 0); +#else + g_error ("kill() is not supported by this platform"); + return FALSE; +#endif } guint32