* arm-apple-darwin9. We'll manually define the symbol on Apple as it does
* in fact exist on all implementations (so far)
*/
-gchar ***_NSGetEnviron(void);
+char ***_NSGetEnviron(void);
#define environ (*_NSGetEnviron())
#else
extern char **environ;
static mono_mutex_t mono_processes_mutex;
static void mono_processes_cleanup (void);
-static mono_once_t process_current_once=MONO_ONCE_INIT;
-static gpointer current_process=NULL;
+static gpointer current_process;
static char *cli_launcher;
-static mono_once_t process_ops_once=MONO_ONCE_INIT;
-
-static void process_ops_init (void)
+static WapiHandle_process *
+lookup_process_handle (gpointer handle)
{
- _wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS,
- WAPI_HANDLE_CAP_WAIT |
- WAPI_HANDLE_CAP_SPECIAL_WAIT);
-}
+ WapiHandle_process *process_data;
+ gboolean ret;
+ ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
+ (gpointer *)&process_data);
+ if (!ret)
+ return NULL;
+ return process_data;
+}
/* Check if a pid is valid - i.e. if a process exists with this pid. */
-static gboolean is_pid_valid (pid_t pid)
+static gboolean
+is_pid_valid (pid_t pid)
{
gboolean result = FALSE;
if (get_team_info ((team_id)pid, &teamInfo) == B_OK)
result = TRUE;
#else
- gchar *dir = g_strdup_printf ("/proc/%d", pid);
+ char *dir = g_strdup_printf ("/proc/%d", pid);
if (!access (dir, F_OK))
result = TRUE;
g_free (dir);
return result;
}
-static void process_set_defaults (struct _WapiHandle_process *process_handle)
+static void
+process_set_defaults (WapiHandle_process *process_handle)
{
/* These seem to be the defaults on w2k */
process_handle->min_working_set = 204800;
return ret;
}
-#ifdef PLATFORM_MACOSX
-
-/* 0 = no detection; -1 = not 10.5 or higher; 1 = 10.5 or higher */
-static int osx_10_5_or_higher;
-
-static void
-detect_osx_10_5_or_higher (void)
-{
- struct utsname u;
- char *p;
- int v;
-
- if (uname (&u) != 0){
- osx_10_5_or_higher = 1;
- return;
- }
-
- p = u.release;
- v = atoi (p);
-
- if (v < 9)
- osx_10_5_or_higher = -1;
- else
- osx_10_5_or_higher = 1;
-}
-
-static gboolean
-is_macos_10_5_or_higher (void)
-{
- if (osx_10_5_or_higher == 0)
- detect_osx_10_5_or_higher ();
-
- return (osx_10_5_or_higher == 1);
-}
-#endif
-
static const gunichar2 utf16_space_bytes [2] = { 0x20, 0 };
static const gunichar2 *utf16_space = utf16_space_bytes;
static const gunichar2 utf16_quote_bytes [2] = { 0x22, 0 };
void
print_utf16 (gunichar2 *str)
{
- gchar *res;
+ char *res;
res = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
g_print ("%s\n", res);
#endif
/* Implemented as just a wrapper around CreateProcess () */
-gboolean ShellExecuteEx (WapiShellExecuteInfo *sei)
+gboolean
+ShellExecuteEx (WapiShellExecuteInfo *sei)
{
gboolean ret;
WapiProcessInformation process_info;
* that
*/
SetLastError (ERROR_INVALID_PARAMETER);
- return (FALSE);
+ return FALSE;
}
- if (sei->lpFile == NULL) {
+ if (sei->lpFile == NULL)
/* w2k returns TRUE for this, for some reason. */
- return (TRUE);
- }
+ return TRUE;
/* Put both executable and parameters into the second argument
* to CreateProcess (), so it searches $PATH. The conversion
* g_strdup_printf () equivalent for gunichar2 :-(
*/
args = utf16_concat (utf16_quote, sei->lpFile, utf16_quote, sei->lpParameters == NULL ? NULL : utf16_space, sei->lpParameters, NULL);
- if (args == NULL){
+ if (args == NULL) {
SetLastError (ERROR_INVALID_DATA);
- return (FALSE);
+ return FALSE;
}
ret = CreateProcess (NULL, args, NULL, NULL, TRUE,
CREATE_UNICODE_ENVIRONMENT, NULL,
handler = g_find_program_in_path ("kfmclient");
if (handler == NULL){
handler_utf16 = (gunichar2 *) -1;
- return (FALSE);
+ return FALSE;
} else {
/* kfmclient needs exec argument */
char *old = handler;
sei->lpFile, utf16_quote,
sei->lpParameters == NULL ? NULL : utf16_space,
sei->lpParameters, NULL);
- if (args == NULL){
+ if (args == NULL) {
SetLastError (ERROR_INVALID_DATA);
return FALSE;
}
CREATE_UNICODE_ENVIRONMENT, NULL,
sei->lpDirectory, NULL, &process_info);
g_free (args);
- if (!ret){
+ if (!ret) {
if (GetLastError () != ERROR_OUTOFMEMORY)
SetLastError (ERROR_INVALID_DATA);
return FALSE;
process_info.hProcess = NULL;
}
- if (sei->fMask & SEE_MASK_NOCLOSEPROCESS) {
+ if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
sei->hProcess = process_info.hProcess;
- } else {
+ else
CloseHandle (process_info.hProcess);
- }
- return (ret);
+ return ret;
}
static gboolean
-is_managed_binary (const gchar *filename)
+is_managed_binary (const char *filename)
{
int original_errno = errno;
#if defined(HAVE_LARGE_FILE_SUPPORT) && defined(O_LARGEFILE)
return managed;
}
-gboolean CreateProcessWithLogonW (const gunichar2 *username,
- const gunichar2 *domain,
- const gunichar2 *password,
- const guint32 logonFlags,
- const gunichar2 *appname,
- const gunichar2 *cmdline,
- guint32 create_flags,
- gpointer env,
- const gunichar2 *cwd,
- WapiStartupInfo *startup,
- WapiProcessInformation *process_info)
+gboolean
+CreateProcessWithLogonW (const gunichar2 *username,
+ const gunichar2 *domain,
+ const gunichar2 *password,
+ const guint32 logonFlags,
+ const gunichar2 *appname,
+ const gunichar2 *cmdline,
+ guint32 create_flags,
+ gpointer env,
+ const gunichar2 *cwd,
+ WapiStartupInfo *startup,
+ WapiProcessInformation *process_info)
{
/* FIXME: use user information */
return CreateProcess (appname, cmdline, NULL, NULL, FALSE, create_flags, env, cwd, startup, process_info);
}
+ static gboolean
+ is_readable (const char *prog)
+ {
+ struct stat buf;
+ if (access (prog, R_OK) != 0)
+ return FALSE;
+ if (stat (prog, &buf))
+ return FALSE;
+ if (S_ISREG (buf.st_mode))
+ return TRUE;
+ return FALSE;
+ }
+
static gboolean
is_executable (const char *prog)
{
}
static void
-switchDirectorySeparators(gchar *path)
+switch_dir_separators (char *path)
{
size_t i, pathLength = strlen(path);
/* Turn all the slashes round the right way, except for \' */
/* There are probably other characters that need to be excluded as well. */
- for (i = 0; i < pathLength; i++)
- {
- if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' ) {
+ for (i = 0; i < pathLength; i++) {
+ if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' )
path[i] = '/';
- }
}
}
WapiStartupInfo *startup,
WapiProcessInformation *process_info)
{
- gchar *cmd=NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL, *dir = NULL, **env_strings = NULL, **argv = NULL;
+ 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;
gboolean ret = FALSE;
gpointer handle;
- struct _WapiHandle_process process_handle = {0}, *process_handle_data;
+ WapiHandle_process process_handle = {0}, *process_handle_data;
GError *gerr = NULL;
int in_fd, out_fd, err_fd;
pid_t pid;
int dummy;
struct MonoProcess *mono_process;
gboolean fork_failed = FALSE;
-
- mono_once (&process_ops_once, process_ops_init);
+
mono_once (&process_sig_chld_once, process_add_sigchld_handler);
-
+
/* appname and cmdline specify the executable and its args:
*
* If appname is not NULL, it is the name of the executable.
goto free_strings;
}
- switchDirectorySeparators(cmd);
+ switch_dir_separators(cmd);
}
if (cmdline != NULL) {
}
/* Turn all the slashes round the right way */
- switchDirectorySeparators(dir);
+ switch_dir_separators(dir);
}
/* We can't put off locating the executable any longer :-( */
if (cmd != NULL) {
- gchar *unquoted;
+ char *unquoted;
if (g_ascii_isalpha (cmd[0]) && (cmd[1] == ':')) {
/* Strip off the drive letter. I can't
* believe that CP/M holdover is still
prog = g_strdup (unquoted);
/* Executable existing ? */
- if (!is_executable (prog)) {
+ if (!is_readable (prog)) {
DEBUG ("%s: Couldn't find executable %s",
__func__, prog);
g_free (unquoted);
prog = g_strdup_printf ("%s/%s", curdir, unquoted);
g_free (curdir);
- /* And make sure it's executable */
- if (!is_executable (prog)) {
+ /* And make sure it's readable */
+ if (!is_readable (prog)) {
DEBUG ("%s: Couldn't find executable %s",
__func__, prog);
g_free (unquoted);
args_after_prog = args;
} else {
- gchar *token = NULL;
+ char *token = NULL;
char quote;
/* Dig out the first token from args, taking quotation
/* Turn all the slashes round the right way. Only for
* the prg. name
*/
- switchDirectorySeparators(token);
+ switch_dir_separators(token);
if (g_ascii_isalpha (token[0]) && (token[1] == ':')) {
/* Strip off the drive letter. I can't
prog = g_strdup (token);
/* Executable existing ? */
- if (!is_executable (prog)) {
+ if (!is_readable (prog)) {
DEBUG ("%s: Couldn't find executable %s",
__func__, token);
g_free (token);
SetLastError (ERROR_FILE_NOT_FOUND);
goto free_strings;
}
-
} else {
char *curdir = g_get_current_dir ();
/* I assume X_OK is the criterion to use,
* rather than F_OK
+ *
+ * X_OK is too strict *if* the target is a CLR binary
*/
- if (!is_executable (prog)) {
+ if (!is_readable (prog)) {
g_free (prog);
prog = g_find_program_in_path (token);
if (prog == NULL) {
goto free_strings;
}
}
+ } 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;
+ }
}
if (args_after_prog != NULL && *args_after_prog) {
- gchar *qprog;
+ char *qprog;
qprog = g_shell_quote (prog);
full_prog = g_strconcat (qprog, " ", args_after_prog, NULL);
err_fd = GPOINTER_TO_UINT (GetStdHandle (STD_ERROR_HANDLE));
}
- g_strlcpy (process_handle.proc_name, prog,
- _WAPI_PROC_NAME_MAX_LEN - 1);
+ process_handle.proc_name = g_strdup (prog);
process_set_defaults (&process_handle);
* environment variables in the new process. Otherwise the
* new process inherits the same environment.
*/
- if (new_environ != NULL) {
+ if (new_environ) {
gunichar2 *new_environp;
/* Count the number of strings */
/* +2: one for the process handle value, and the last
* one is NULL
*/
- env_strings = g_new0 (gchar *, env_count + 2);
+ env_strings = g_new0 (char *, env_count + 2);
/* Copy each environ string into 'strings' turning it
* into utf8 (or the requested encoding) at the same
}
}
} else {
- for (i = 0; environ[i] != NULL; i++) {
+ for (i = 0; environ[i] != NULL; i++)
env_count++;
- }
/* +2: one for the process handle value, and the last
* one is NULL
*/
- env_strings = g_new0 (gchar *, env_count + 2);
+ env_strings = g_new0 (char *, env_count + 2);
/* Copy each environ string into 'strings' turning it
* into utf8 (or the requested encoding) at the same
env_count++;
}
}
- /* pass process handle info to the child, so it doesn't have
- * to do an expensive search over the whole list
- */
- if (env_strings != NULL) {
- struct _WapiHandleUnshared *handle_data;
- struct _WapiHandle_shared_ref *ref;
-
- handle_data = &_WAPI_PRIVATE_HANDLES(GPOINTER_TO_UINT(handle));
- ref = &handle_data->u.shared;
-
- env_strings[env_count] = g_strdup_printf ("_WAPI_PROCESS_HANDLE_OFFSET=%d", ref->offset);
- }
/* Create a pipe to make sure the child doesn't exit before
* we can add the process to the linked list of mono_processes */
}
/* Close all file descriptors */
- for (i = getdtablesize () - 1; i > 2; i--) {
+ for (i = wapi_getdtablesize () - 1; i > 2; i--)
close (i);
- }
#ifdef DEBUG_ENABLED
DEBUG ("%s: exec()ing [%s] in dir [%s]", __func__, cmd,
- dir==NULL?".":dir);
- for (i = 0; argv[i] != NULL; i++) {
+ dir == NULL?".":dir);
+ for (i = 0; argv[i] != NULL; i++)
g_message ("arg %d: [%s]", i, argv[i]);
- }
- for (i = 0; env_strings[i] != NULL; i++) {
+ for (i = 0; env_strings[i] != NULL; i++)
g_message ("env %d: [%s]", i, env_strings[i]);
- }
#endif
/* set cwd */
}
/* parent */
- ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle_data);
- if (ret == FALSE) {
+ process_handle_data = lookup_process_handle (handle);
+ if (!process_handle_data) {
g_warning ("%s: error looking up process handle %p", __func__,
handle);
_wapi_handle_unref (handle);
_wapi_handle_ref (handle);
mono_process->handle = handle;
- process_handle_data->self = _wapi_getpid ();
process_handle_data->mono_process = mono_process;
mono_mutex_lock (&mono_processes_mutex);
}
free_strings:
- if (cmd != NULL) {
+ if (cmd)
g_free (cmd);
- }
- if (full_prog != NULL) {
+ if (full_prog)
g_free (full_prog);
- }
- if (prog != NULL) {
+ if (prog)
g_free (prog);
- }
- if (args != NULL) {
+ if (args)
g_free (args);
- }
- if (dir != NULL) {
+ if (dir)
g_free (dir);
- }
- if(env_strings != NULL) {
+ if (env_strings)
g_strfreev (env_strings);
- }
- if (argv != NULL) {
+ if (argv)
g_strfreev (argv);
- }
DEBUG ("%s: returning handle %p for pid %d", __func__, handle,
pid);
/* Check if something needs to be cleaned up. */
mono_processes_cleanup ();
- return(ret);
+ return ret;
}
-static void process_set_name (struct _WapiHandle_process *process_handle)
+static void
+process_set_name (WapiHandle_process *process_handle)
{
- gchar *progname, *utf8_progname, *slash;
+ char *progname, *utf8_progname, *slash;
- progname=g_get_prgname ();
- utf8_progname=mono_utf8_from_external (progname);
+ progname = g_get_prgname ();
+ utf8_progname = mono_utf8_from_external (progname);
DEBUG ("%s: using [%s] as prog name", __func__, progname);
- if(utf8_progname!=NULL) {
- slash=strrchr (utf8_progname, '/');
- if(slash!=NULL) {
- g_strlcpy (process_handle->proc_name, slash+1,
- _WAPI_PROC_NAME_MAX_LEN - 1);
- } else {
- g_strlcpy (process_handle->proc_name, utf8_progname,
- _WAPI_PROC_NAME_MAX_LEN - 1);
- }
-
+ if (utf8_progname) {
+ slash = strrchr (utf8_progname, '/');
+ if (slash)
+ process_handle->proc_name = g_strdup (slash+1);
+ else
+ process_handle->proc_name = g_strdup (utf8_progname);
g_free (utf8_progname);
}
}
-extern void _wapi_time_t_to_filetime (time_t timeval, WapiFileTime *filetime);
-
-#if !GLIB_CHECK_VERSION (2,4,0)
-#define g_setenv(a,b,c) setenv(a,b,c)
-#define g_unsetenv(a) unsetenv(a)
-#endif
-
-static void process_set_current (void)
+void
+wapi_processes_init (void)
{
pid_t pid = _wapi_getpid ();
- const char *handle_env;
- struct _WapiHandle_process process_handle = {0};
-
- mono_once (&process_ops_once, process_ops_init);
-
- handle_env = g_getenv ("_WAPI_PROCESS_HANDLE_OFFSET");
- g_unsetenv ("_WAPI_PROCESS_HANDLE_OFFSET");
-
- if (handle_env != NULL) {
- struct _WapiHandle_process *process_handlep;
- gchar *procname = NULL;
- gboolean ok;
-
- current_process = _wapi_handle_new_from_offset (WAPI_HANDLE_PROCESS, atoi (handle_env), TRUE);
-
- DEBUG ("%s: Found my process handle: %p (offset %d 0x%x)",
- __func__, current_process, atoi (handle_env),
- atoi (handle_env));
-
- ok = _wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handlep);
- if (ok) {
- /* This test will probably break on linuxthreads, but
- * that should be ancient history on all distros we
- * care about by now
- */
- if (process_handlep->id == pid) {
- procname = process_handlep->proc_name;
- if (!strcmp (procname, "mono")) {
- /* Set a better process name */
- DEBUG ("%s: Setting better process name", __func__);
-
- process_set_name (process_handlep);
- } else {
- DEBUG ("%s: Leaving process name: %s", __func__, procname);
- }
-
- return;
- }
-
- /* Wrong pid, so drop this handle and fall through to
- * create a new one
- */
- _wapi_handle_unref (current_process);
- }
- }
-
- /* We get here if the handle wasn't specified in the
- * environment, or if the process ID was wrong, or if the
- * handle lookup failed (eg if the parent process forked and
- * quit immediately, and deleted the shared data before the
- * child got a chance to attach it.)
- */
-
- DEBUG ("%s: Need to create my own process handle", __func__);
+ WapiHandle_process process_handle = {0};
+ _wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS,
+ WAPI_HANDLE_CAP_WAIT |
+ WAPI_HANDLE_CAP_SPECIAL_WAIT);
+
process_handle.id = pid;
process_set_defaults (&process_handle);
current_process = _wapi_handle_new (WAPI_HANDLE_PROCESS,
&process_handle);
- if (current_process == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating process handle", __func__);
- return;
- }
+ g_assert (current_process);
}
-gpointer _wapi_process_duplicate ()
+gpointer
+_wapi_process_duplicate (void)
{
- mono_once (&process_current_once, process_set_current);
-
_wapi_handle_ref (current_process);
- return(current_process);
+ return current_process;
}
/* Returns a pseudo handle that doesn't need to be closed afterwards */
-gpointer GetCurrentProcess (void)
+gpointer
+GetCurrentProcess (void)
{
- mono_once (&process_current_once, process_set_current);
-
- return(_WAPI_PROCESS_CURRENT);
+ return _WAPI_PROCESS_CURRENT;
}
-guint32 GetProcessId (gpointer handle)
+guint32
+GetProcessId (gpointer handle)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
- if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
/* This is a pseudo handle */
- return(GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
- }
+ return WAPI_HANDLE_TO_PID (handle);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if (ok == FALSE) {
+ process_handle = lookup_process_handle (handle);
+ if (!process_handle) {
SetLastError (ERROR_INVALID_HANDLE);
- return (0);
+ return 0;
}
- return (process_handle->id);
+ return process_handle->id;
}
-guint32 GetCurrentProcessId (void)
+static gboolean
+process_open_compare (gpointer handle, gpointer user_data)
{
- mono_once (&process_current_once, process_set_current);
-
- return (GetProcessId (current_process));
-}
+ pid_t wanted_pid;
+ WapiHandle_process *process_handle;
+ pid_t checking_pid;
-/* Returns the process id as a convenience to the functions that call this */
-static pid_t signal_process_if_gone (gpointer handle)
-{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ g_assert (!WAPI_IS_PSEUDO_PROCESS_HANDLE (handle));
- g_assert ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) != _WAPI_PROCESS_UNHANDLED);
-
- /* Make sure the process is signalled if it has exited - if
- * the parent process didn't wait for it then it won't be
- */
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if (ok == FALSE) {
- /* It's possible that the handle has vanished during
- * the _wapi_search_handle before it gets here, so
- * don't spam the console with warnings.
- */
-/* g_warning ("%s: error looking up process handle %p",
- __func__, handle);*/
-
- return (0);
- }
+ process_handle = lookup_process_handle (handle);
+ g_assert (process_handle);
DEBUG ("%s: looking at process %d", __func__, process_handle->id);
- if (kill (process_handle->id, 0) == -1 &&
- (errno == ESRCH ||
- errno == EPERM)) {
- /* The process is dead, (EPERM tells us a new process
- * has that ID, but as it's owned by someone else it
- * can't be the one listed in our shared memory file)
- */
- _wapi_shared_handle_set_signal_state (handle, TRUE);
- }
-
- return (process_handle->id);
-}
-
-#ifdef UNUSED_CODE
-static gboolean process_enum (gpointer handle, gpointer user_data)
-{
- GArray *processes=user_data;
- pid_t pid = signal_process_if_gone (handle);
- int i;
-
- if (pid == 0) {
- return (FALSE);
- }
-
- /* Ignore processes that have already exited (ie they are signalled) */
- if (_wapi_handle_issignalled (handle) == FALSE) {
- DEBUG ("%s: process %d added to array", __func__, pid);
-
- /* This ensures that duplicates aren't returned (see
- * the comment above _wapi_search_handle () for why
- * it's needed
- */
- for (i = 0; i < processes->len; i++) {
- if (g_array_index (processes, pid_t, i) == pid) {
- /* We've already got this one, return
- * FALSE to keep searching
- */
- return (FALSE);
- }
- }
-
- g_array_append_val (processes, pid);
- }
-
- /* Return false to keep searching */
- return(FALSE);
-}
-#endif /* UNUSED_CODE */
-
-#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_proc *result;
- int name[6];
- name[0] = CTL_KERN;
- name[1] = KERN_PROC;
- name[2] = KERN_PROC_ALL;
- name[3] = 0;
- name[4] = sizeof(struct kinfo_proc);
- name[5] = 0;
-#else
- struct kinfo_proc *result;
- static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
-#endif
-
- mono_once (&process_current_once, process_set_current);
-
- result = NULL;
- done = FALSE;
-
- do {
- proclength = 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;
+ checking_pid = process_handle->id;
-#if defined(__OpenBSD__)
- name[5] = (int)(proclength / sizeof(struct kinfo_proc));
-#endif
-
- err = sysctl ((int *) name, size, result, &proclength, NULL, 0);
-
- if (err == 0)
- done = TRUE;
- else {
- free (result);
- result = NULL;
- }
- }
- } 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++) {
-#if defined(__OpenBSD__)
- pids [j++] = result [i].p_pid;
-#else
- if (result[i].kp_proc.p_pid > 0) /* Pid 0 not supported */
- pids [j++] = result [i].kp_proc.p_pid;
-#endif
- }
- free (result);
- result = NULL;
- *needed = j * sizeof(guint32);
-
- return(TRUE);
-}
-#elif defined(__HAIKU__)
-
-gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
-{
- guint32 fit, i = 0;
- int32 cookie = 0;
- team_info teamInfo;
-
- mono_once (&process_current_once, process_set_current);
-
- fit = len / sizeof (guint32);
- while (get_next_team_info (&cookie, &teamInfo) == B_OK && i < fit) {
- pids [i++] = teamInfo.team;
- }
- *needed = i * sizeof (guint32);
-
- return TRUE;
-}
-#else
-gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed)
-{
- guint32 fit, i;
- DIR *dir;
- struct dirent *entry;
-
- mono_once (&process_current_once, process_set_current);
-
- dir = opendir ("/proc");
- if (dir == NULL) {
- return(FALSE);
- }
-
- i = 0;
- fit = len / sizeof (guint32);
- while(i < fit && (entry = readdir (dir)) != NULL) {
- pid_t pid;
- char *endptr;
-
- if (!isdigit (entry->d_name[0]))
- continue;
-
- pid = (pid_t) strtol (entry->d_name, &endptr, 10);
- if (*endptr == '\0')
- pids [i++] = (guint32) pid;
- }
- closedir (dir);
- *needed = i * sizeof(guint32);
-
- return(TRUE);
-}
-#endif
-
-static gboolean process_open_compare (gpointer handle, gpointer user_data)
-{
- pid_t wanted_pid;
- pid_t checking_pid = signal_process_if_gone (handle);
-
- if (checking_pid == 0) {
- return(FALSE);
- }
+ if (checking_pid == 0)
+ return FALSE;
wanted_pid = GPOINTER_TO_UINT (user_data);
* unsignalled
*/
if (checking_pid == wanted_pid &&
- _wapi_handle_issignalled (handle) == FALSE) {
+ !_wapi_handle_issignalled (handle)) {
/* If the handle is blown away in the window between
* returning TRUE here and _wapi_search_handle pinging
* the timestamp, the search will continue
*/
- return(TRUE);
+ return TRUE;
} else {
- return(FALSE);
+ return FALSE;
}
}
-gboolean CloseProcess(gpointer handle)
+gboolean
+CloseProcess (gpointer handle)
{
- if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
- /* This is a pseudo handle */
- return(TRUE);
- }
-
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
+ return TRUE;
return CloseHandle (handle);
}
/*
* The caller owns the returned handle and must call CloseProcess () on it to clean it up.
*/
-gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid)
+gpointer
+OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid)
{
/* Find the process handle that corresponds to pid */
gpointer handle = NULL;
- mono_once (&process_current_once, process_set_current);
-
DEBUG ("%s: looking for process %d", __func__, pid);
handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
/* Return a pseudo handle for processes we
* don't have handles for
*/
- return GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + pid);
+ return WAPI_PID_TO_HANDLE (pid);
} else {
DEBUG ("%s: Can't find pid %d", __func__, pid);
SetLastError (ERROR_PROC_NOT_FOUND);
- return(NULL);
+ return NULL;
}
}
/* _wapi_search_handle () already added a ref */
- return(handle);
+ return handle;
}
-gboolean GetExitCodeProcess (gpointer process, guint32 *code)
+gboolean
+GetExitCodeProcess (gpointer process, guint32 *code)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
guint32 pid = -1;
- mono_once (&process_current_once, process_set_current);
-
- if(code==NULL) {
- return(FALSE);
- }
+ if (!code)
+ return FALSE;
- pid = GPOINTER_TO_UINT (process) - _WAPI_PROCESS_UNHANDLED;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
+ pid = WAPI_HANDLE_TO_PID (process);
/* This is a pseudo handle, so we don't know what the
* exit code was, but we can check whether it's alive or not
*/
}
}
- ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if(ok==FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__, process);
- return(FALSE);
+ return FALSE;
}
/* A process handle is only signalled if the process has exited
*/
process_wait (process, 0, TRUE);
- if (_wapi_handle_issignalled (process) == TRUE) {
+ if (_wapi_handle_issignalled (process))
*code = process_handle->exitstatus;
- } else {
+ else
*code = STILL_ACTIVE;
- }
- return(TRUE);
+ return TRUE;
}
-gboolean GetProcessTimes (gpointer process, WapiFileTime *create_time,
- WapiFileTime *exit_time, WapiFileTime *kernel_time,
- WapiFileTime *user_time)
+gboolean
+GetProcessTimes (gpointer process, WapiFileTime *create_time,
+ WapiFileTime *exit_time, WapiFileTime *kernel_time,
+ WapiFileTime *user_time)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
gboolean ku_times_set = FALSE;
- mono_once (&process_current_once, process_set_current);
-
- if(create_time==NULL || exit_time==NULL || kernel_time==NULL ||
- user_time==NULL) {
+ if (create_time == NULL || exit_time == NULL || kernel_time == NULL ||
+ user_time == NULL)
/* Not sure if w32 allows NULLs here or not */
- return(FALSE);
- }
+ return FALSE;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process))
/* This is a pseudo handle, so just fail for now
*/
- return(FALSE);
- }
+ return FALSE;
- ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if(ok==FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__, process);
- return(FALSE);
+ return FALSE;
}
- *create_time=process_handle->create_time;
+ *create_time = process_handle->create_time;
/* A process handle is only signalled if the process has
* exited. Otherwise exit_time isn't set
*/
- if(_wapi_handle_issignalled (process)==TRUE) {
- *exit_time=process_handle->exit_time;
- }
+ if (_wapi_handle_issignalled (process))
+ *exit_time = process_handle->exit_time;
#ifdef HAVE_GETRUSAGE
if (process_handle->id == getpid ()) {
memset (user_time, 0, sizeof (WapiFileTime));
}
- return(TRUE);
+ return TRUE;
}
typedef struct
{
gpointer address_start;
gpointer address_end;
- gchar *perms;
+ char *perms;
gpointer address_offset;
dev_t device;
ino_t inode;
- gchar *filename;
+ char *filename;
} WapiProcModule;
static void free_procmodule (WapiProcModule *mod)
{
GSList *ret = NULL;
WapiProcModule *mod;
- gchar buf[MAXPATHLEN + 1], *p, *endp;
- gchar *start_start, *end_start, *prot_start, *offset_start;
- gchar *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5];
+ char buf[MAXPATHLEN + 1], *p, *endp;
+ char *start_start, *end_start, *prot_start, *offset_start;
+ char *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5];
gpointer address_start, address_end, address_offset;
guint32 maj_dev, min_dev;
ino_t inode;
}
#endif
-static gboolean match_procname_to_modulename (gchar *procname, gchar *modulename)
+static gboolean match_procname_to_modulename (char *procname, char *modulename)
{
char* lastsep = NULL;
char* lastsep2 = NULL;
open_process_map (int pid, const char *mode)
{
FILE *fp = NULL;
- const gchar *proc_path[] = {
+ const char *proc_path[] = {
"/proc/%d/maps", /* GNU/Linux */
"/proc/%d/map", /* FreeBSD */
NULL
};
int i;
- gchar *filename;
+ char *filename;
for (i = 0; fp == NULL && proc_path [i]; i++) {
filename = g_strdup_printf (proc_path[i], pid);
gboolean EnumProcessModules (gpointer process, gpointer *modules,
guint32 size, guint32 *needed)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX)
FILE *fp;
#endif
guint32 count, avail = size / sizeof(gpointer);
int i;
pid_t pid;
- gchar *proc_name = NULL;
+ char *proc_name = NULL;
/* Store modules in an array of pointers (main module as
* modules[0]), using the load address for each module as a
* implement /dev/kmem reading or whatever other horrid
* technique is needed.
*/
- if (size < sizeof(gpointer)) {
- return(FALSE);
- }
+ if (size < sizeof(gpointer))
+ return FALSE;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
- /* This is a pseudo handle */
- pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
+ pid = WAPI_HANDLE_TO_PID (process);
} else {
- ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if (ok == FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__, process);
- return(FALSE);
+ return FALSE;
}
pid = process_handle->id;
proc_name = process_handle->proc_name;
}
#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)
- {
- mods = load_modules ();
+ mods = load_modules ();
+ if (!proc_name) {
+ modules[0] = NULL;
+ *needed = sizeof(gpointer);
+ return TRUE;
+ }
#else
- if ((fp = open_process_map (pid, "r")) == NULL) {
+ fp = open_process_map (pid, "r");
+ if (!fp) {
/* No /proc/<pid>/maps so just return the main module
* shortcut for now
*/
modules[0] = NULL;
*needed = sizeof(gpointer);
- } else {
- mods = load_modules (fp);
- fclose (fp);
+ return TRUE;
+ }
+ mods = load_modules (fp);
+ fclose (fp);
#endif
- count = g_slist_length (mods);
+ count = g_slist_length (mods);
- /* count + 1 to leave slot 0 for the main module */
- *needed = sizeof(gpointer) * (count + 1);
-
- /* Use the NULL shortcut, as the first line in
- * /proc/<pid>/maps isn't the executable, and we need
- * that first in the returned list. Check the module name
- * to see if it ends with the proc name and substitute
- * the first entry with it. FIXME if this turns out to
- * be a problem.
- */
- modules[0] = NULL;
- for (i = 0; i < (avail - 1) && i < count; i++) {
- module = (WapiProcModule *)g_slist_nth_data (mods, i);
- if (modules[0] != NULL)
- modules[i] = module->address_start;
- else if (match_procname_to_modulename (proc_name, module->filename))
- modules[0] = module->address_start;
- else
- modules[i + 1] = module->address_start;
- }
+ /* count + 1 to leave slot 0 for the main module */
+ *needed = sizeof(gpointer) * (count + 1);
+
+ /*
+ * Use the NULL shortcut, as the first line in
+ * /proc/<pid>/maps isn't the executable, and we need
+ * that first in the returned list. Check the module name
+ * to see if it ends with the proc name and substitute
+ * the first entry with it. FIXME if this turns out to
+ * be a problem.
+ */
+ modules[0] = NULL;
+ for (i = 0; i < (avail - 1) && i < count; i++) {
+ module = (WapiProcModule *)g_slist_nth_data (mods, i);
+ if (modules[0] != NULL)
+ modules[i] = module->address_start;
+ else if (match_procname_to_modulename (proc_name, module->filename))
+ modules[0] = module->address_start;
+ else
+ modules[i + 1] = module->address_start;
+ }
- for (i = 0; i < count; i++) {
- free_procmodule (g_slist_nth_data (mods, i));
- }
- g_slist_free (mods);
+ for (i = 0; i < count; i++) {
+ free_procmodule (g_slist_nth_data (mods, i));
}
+ g_slist_free (mods);
- return(TRUE);
+ return TRUE;
}
-static gchar *get_process_name_from_proc (pid_t pid)
+static char *
+get_process_name_from_proc (pid_t pid)
{
#if defined(__OpenBSD__)
int mib [6];
#endif
#else
FILE *fp;
- gchar *filename = NULL;
+ char *filename = NULL;
#endif
- gchar buf[256];
- gchar *ret = NULL;
+ char buf[256];
+ char *ret = NULL;
#if defined(PLATFORM_SOLARIS)
filename = g_strdup_printf ("/proc/%d/psinfo", pid);
filename = g_strdup_printf ("/proc/%d/stat", pid);
if ((fp = fopen (filename, "r")) != NULL) {
if (fgets (buf, 256, fp) != NULL) {
- gchar *start, *end;
+ char *start, *end;
start = strchr (buf, '(');
if (start != NULL) {
* Return the full path of the executable of the process PID, or NULL if it cannot be determined.
* Returns malloc-ed memory.
*/
-gchar*
+char*
wapi_process_get_path (pid_t pid)
{
#if defined(PLATFORM_MACOSX) && !defined(__mono_ppc__) && defined(TARGET_OSX)
- gchar buf [PROC_PIDPATHINFO_MAXSIZE];
+ char buf [PROC_PIDPATHINFO_MAXSIZE];
int res;
res = proc_pidpath (pid, buf, sizeof (buf));
cli_launcher = path ? g_strdup (path) : NULL;
}
-static guint32 get_module_name (gpointer process, gpointer module,
- gunichar2 *basename, guint32 size,
- gboolean base)
+static guint32
+get_module_name (gpointer process, gpointer module,
+ gunichar2 *basename, guint32 size,
+ gboolean base)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
pid_t pid;
gunichar2 *procname;
- gchar *procname_ext = NULL;
+ char *procname_ext = NULL;
glong len;
gsize bytes;
#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX)
WapiProcModule *found_module;
guint32 count;
int i;
- gchar *proc_name = NULL;
+ char *proc_name = NULL;
- mono_once (&process_current_once, process_set_current);
-
DEBUG ("%s: Getting module base name, process handle %p module %p",
__func__, process, module);
- size = size*sizeof(gunichar2); /* adjust for unicode characters */
+ size = size * sizeof (gunichar2); /* adjust for unicode characters */
- if (basename == NULL || size == 0) {
- return(0);
- }
+ if (basename == NULL || size == 0)
+ return 0;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
/* This is a pseudo handle */
- pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
+ pid = (pid_t)WAPI_HANDLE_TO_PID (process);
proc_name = get_process_name_from_proc (pid);
} else {
- ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if (ok == FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__,
process);
- return(0);
+ return 0;
}
pid = process_handle->id;
proc_name = g_strdup (process_handle->proc_name);
/* Look up the address in /proc/<pid>/maps */
#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)
- {
- mods = load_modules ();
+ mods = load_modules ();
#else
- if ((fp = open_process_map (pid, "r")) == NULL) {
+ fp = open_process_map (pid, "r");
+ if (fp == NULL) {
if (errno == EACCES && module == NULL && base == TRUE) {
procname_ext = get_process_name_from_proc (pid);
} else {
* for now
*/
g_free (proc_name);
- return(0);
+ return 0;
}
} else {
mods = load_modules (fp);
fclose (fp);
+ }
#endif
- count = g_slist_length (mods);
-
- /* If module != NULL compare the address.
- * If module == NULL we are looking for the main module.
- * The best we can do for now check it the module name end with the process name.
- */
- for (i = 0; i < count; i++) {
- found_module = (WapiProcModule *)g_slist_nth_data (mods, i);
- if (procname_ext == NULL &&
- ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
- (module != NULL && found_module->address_start == module))) {
- if (base) {
- procname_ext = g_path_get_basename (found_module->filename);
- } else {
- procname_ext = g_strdup (found_module->filename);
- }
- }
+ count = g_slist_length (mods);
- free_procmodule (found_module);
+ /* If module != NULL compare the address.
+ * If module == NULL we are looking for the main module.
+ * The best we can do for now check it the module name end with the process name.
+ */
+ for (i = 0; i < count; i++) {
+ found_module = (WapiProcModule *)g_slist_nth_data (mods, i);
+ if (procname_ext == NULL &&
+ ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
+ (module != NULL && found_module->address_start == module))) {
+ if (base)
+ procname_ext = g_path_get_basename (found_module->filename);
+ else
+ procname_ext = g_strdup (found_module->filename);
}
- if (procname_ext == NULL)
- {
- /* If it's *still* null, we might have hit the
- * case where reading /proc/$pid/maps gives an
- * empty file for this user.
- */
- procname_ext = get_process_name_from_proc (pid);
- }
+ free_procmodule (found_module);
+ }
- g_slist_free (mods);
- g_free (proc_name);
+ if (procname_ext == NULL) {
+ /* If it's *still* null, we might have hit the
+ * case where reading /proc/$pid/maps gives an
+ * empty file for this user.
+ */
+ procname_ext = get_process_name_from_proc (pid);
}
- if (procname_ext != NULL) {
+ g_slist_free (mods);
+ g_free (proc_name);
+
+ if (procname_ext) {
DEBUG ("%s: Process name is [%s]", __func__,
procname_ext);
if (procname == NULL) {
/* bugger */
g_free (procname_ext);
- return(0);
+ return 0;
}
len = (bytes / 2);
g_free (procname);
g_free (procname_ext);
- return(len);
+ return len;
}
- return(0);
+ return 0;
}
-guint32 GetModuleBaseName (gpointer process, gpointer module,
- gunichar2 *basename, guint32 size)
+guint32
+GetModuleBaseName (gpointer process, gpointer module,
+ gunichar2 *basename, guint32 size)
{
- return(get_module_name (process, module, basename, size, TRUE));
+ return get_module_name (process, module, basename, size, TRUE);
}
-guint32 GetModuleFileNameEx (gpointer process, gpointer module,
- gunichar2 *filename, guint32 size)
+guint32
+GetModuleFileNameEx (gpointer process, gpointer module,
+ gunichar2 *filename, guint32 size)
{
- return(get_module_name (process, module, filename, size, FALSE));
+ return get_module_name (process, module, filename, size, FALSE);
}
-gboolean GetModuleInformation (gpointer process, gpointer module,
- WapiModuleInfo *modinfo, guint32 size)
+gboolean
+GetModuleInformation (gpointer process, gpointer module,
+ WapiModuleInfo *modinfo, guint32 size)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
pid_t pid;
#if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX)
FILE *fp;
guint32 count;
int i;
gboolean ret = FALSE;
- gchar *proc_name = NULL;
-
- mono_once (&process_current_once, process_set_current);
+ char *proc_name = NULL;
DEBUG ("%s: Getting module info, process handle %p module %p",
__func__, process, module);
- if (modinfo == NULL || size < sizeof(WapiModuleInfo)) {
- return(FALSE);
- }
+ if (modinfo == NULL || size < sizeof (WapiModuleInfo))
+ return FALSE;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
- /* This is a pseudo handle */
- pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
+ pid = (pid_t)WAPI_HANDLE_TO_PID (process);
proc_name = get_process_name_from_proc (pid);
} else {
- ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if (ok == FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__,
process);
- return(FALSE);
+ return FALSE;
}
pid = process_handle->id;
proc_name = g_strdup (process_handle->proc_name);
}
#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__)
- {
- mods = load_modules ();
+ mods = load_modules ();
#else
/* Look up the address in /proc/<pid>/maps */
if ((fp = open_process_map (pid, "r")) == NULL) {
* for now
*/
g_free (proc_name);
- return(FALSE);
- } else {
- mods = load_modules (fp);
- fclose (fp);
+ return FALSE;
+ }
+ mods = load_modules (fp);
+ fclose (fp);
#endif
- count = g_slist_length (mods);
+ count = g_slist_length (mods);
- /* If module != NULL compare the address.
- * If module == NULL we are looking for the main module.
- * The best we can do for now check it the module name end with the process name.
- */
- for (i = 0; i < count; i++) {
+ /* If module != NULL compare the address.
+ * If module == NULL we are looking for the main module.
+ * The best we can do for now check it the module name end with the process name.
+ */
+ for (i = 0; i < count; i++) {
found_module = (WapiProcModule *)g_slist_nth_data (mods, i);
- if ( ret == FALSE &&
- ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
- (module != NULL && found_module->address_start == module))) {
+ if (ret == FALSE &&
+ ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
+ (module != NULL && found_module->address_start == module))) {
modinfo->lpBaseOfDll = found_module->address_start;
modinfo->SizeOfImage = (gsize)(found_module->address_end) - (gsize)(found_module->address_start);
modinfo->EntryPoint = found_module->address_offset;
}
free_procmodule (found_module);
- }
-
- g_slist_free (mods);
- g_free (proc_name);
}
- return(ret);
+ g_slist_free (mods);
+ g_free (proc_name);
+
+ return ret;
}
-gboolean GetProcessWorkingSetSize (gpointer process, size_t *min, size_t *max)
+gboolean
+GetProcessWorkingSetSize (gpointer process, size_t *min, size_t *max)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
- mono_once (&process_current_once, process_set_current);
-
- if(min==NULL || max==NULL) {
+ if (min == NULL || max == NULL)
/* Not sure if w32 allows NULLs here or not */
- return(FALSE);
- }
+ return FALSE;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
- /* This is a pseudo handle, so just fail for now
- */
- return(FALSE);
- }
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process))
+ /* This is a pseudo handle, so just fail for now */
+ return FALSE;
- ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if(ok==FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__, process);
- return(FALSE);
+ return FALSE;
}
- *min=process_handle->min_working_set;
- *max=process_handle->max_working_set;
+ *min = process_handle->min_working_set;
+ *max = process_handle->max_working_set;
- return(TRUE);
+ return TRUE;
}
-gboolean SetProcessWorkingSetSize (gpointer process, size_t min, size_t max)
+gboolean
+SetProcessWorkingSetSize (gpointer process, size_t min, size_t max)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
- mono_once (&process_current_once, process_set_current);
-
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process))
/* This is a pseudo handle, so just fail for now
*/
- return(FALSE);
- }
+ return FALSE;
- ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if(ok==FALSE) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
DEBUG ("%s: Can't find process %p", __func__, process);
- return(FALSE);
+ return FALSE;
}
- process_handle->min_working_set=min;
- process_handle->max_working_set=max;
+ process_handle->min_working_set = min;
+ process_handle->max_working_set = max;
- return(TRUE);
+ return TRUE;
}
gboolean
TerminateProcess (gpointer process, gint32 exitCode)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
int signo;
int ret;
pid_t pid;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
/* This is a pseudo handle */
- pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
+ pid = (pid_t)WAPI_HANDLE_TO_PID (process);
} else {
- ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *) &process_handle);
-
- if (ok == FALSE) {
- DEBUG ("%s: Can't find process %p", __func__,
- process);
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
+ DEBUG ("%s: Can't find process %p", __func__, process);
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
GetPriorityClass (gpointer process)
{
#ifdef HAVE_GETPRIORITY
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
int ret;
pid_t pid;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
/* This is a pseudo handle */
- pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
+ pid = (pid_t)WAPI_HANDLE_TO_PID (process);
} else {
- ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *) &process_handle);
-
- if (!ok) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
SetPriorityClass (gpointer process, guint32 priority_class)
{
#ifdef HAVE_SETPRIORITY
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
int ret;
int prio;
pid_t pid;
- if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
+ if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
/* This is a pseudo handle */
- pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK);
+ pid = (pid_t)WAPI_HANDLE_TO_PID (process);
} else {
- ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS,
- (gpointer *) &process_handle);
-
- if (!ok) {
+ process_handle = lookup_process_handle (process);
+ if (!process_handle) {
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
mp = mp->next;
}
+ /*
+ * Remove processes which exited from the mono_processes list.
+ * We need to synchronize with the sigchld handler here, which runs
+ * asynchronously. The handler requires that the mono_processes list
+ * remain valid.
+ */
mp = mono_processes;
spin = 0;
while (mp != NULL) {
/* We've found a candidate */
mono_mutex_lock (&mono_processes_mutex);
+ /*
+ * This code can run parallel with the sigchld handler, but the
+ * modifications it makes are safe.
+ */
if (candidate == NULL) {
/* unlink it */
if (mp == mono_processes) {
static void
process_close (gpointer handle, gpointer data)
{
- struct _WapiHandle_process *process_handle;
+ WapiHandle_process *process_handle;
DEBUG ("%s", __func__);
- process_handle = (struct _WapiHandle_process *) data;
- if (process_handle->mono_process && process_handle->self == _wapi_getpid ())
+ process_handle = (WapiHandle_process *) data;
+ g_free (process_handle->proc_name);
+ process_handle->proc_name = NULL;
+ if (process_handle->mono_process)
InterlockedDecrement (&process_handle->mono_process->handle_count);
mono_processes_cleanup ();
}
int pid;
struct MonoProcess *p;
-#if DEBUG
- fprintf (stdout, "SIG CHILD handler for pid: %i\n", info->si_pid);
-#endif
+ DEBUG ("SIG CHILD handler for pid: %i\n", info->si_pid);
InterlockedIncrement (&mono_processes_read_lock);
if (pid <= 0)
break;
-#if DEBUG
- fprintf (stdout, "child ended: %i", pid);
-#endif
+ DEBUG ("child ended: %i", pid);
p = mono_processes;
while (p != NULL) {
if (p->pid == pid) {
InterlockedDecrement (&mono_processes_read_lock);
-#if DEBUG
- fprintf (stdout, "SIG CHILD handler: done looping.");
-#endif
+ DEBUG ("SIG CHILD handler: done looping.");
}
#endif
-static void process_add_sigchld_handler (void)
+static void
+process_add_sigchld_handler (void)
{
#if HAVE_SIGACTION
struct sigaction sa;
#endif
}
-static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertable)
+static guint32
+process_wait (gpointer handle, guint32 timeout, gboolean alertable)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
+ WapiHandle_process *process_handle;
pid_t pid, ret;
int status;
guint32 start;
guint32 now;
struct MonoProcess *mp;
- gboolean spin;
- gpointer current_thread;
-
- current_thread = wapi_get_current_thread_handle ();
- if (current_thread == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
- return WAIT_FAILED;
- }
/* FIXME: We can now easily wait on processes that aren't our own children,
* but WaitFor*Object won't call us for pseudo handles. */
DEBUG ("%s (%p, %u)", __func__, handle, timeout);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, (gpointer *)&process_handle);
- if (ok == FALSE) {
+ process_handle = lookup_process_handle (handle);
+ if (!process_handle) {
g_warning ("%s: error looking up process handle %p", __func__, handle);
return WAIT_FAILED;
}
/* We don't need to lock mono_processes here, the entry
* has a handle_count > 0 which means it will not be freed. */
mp = process_handle->mono_process;
- if (mp && process_handle->self != _wapi_getpid ()) {
- /* mono_process points to memory in another process' address space: we can't use it */
- mp = NULL;
- }
+ g_assert (mp);
start = mono_msec_ticks ();
now = start;
- spin = mp == NULL;
while (1) {
- if (mp != NULL) {
- /* We have a semaphore we can wait on */
- if (timeout != INFINITE) {
- DEBUG ("%s (%p, %u): waiting on semaphore for %li ms...",
- __func__, handle, timeout, (timeout - (now - start)));
+ 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);
- } else {
- DEBUG ("%s (%p, %u): waiting on semaphore forever...",
- __func__, handle, timeout);
- ret = MONO_SEM_WAIT_ALERTABLE (&mp->exit_sem, alertable);
- }
+ ret = MONO_SEM_TIMEDWAIT_ALERTABLE (&mp->exit_sem, (timeout - (now - start)), alertable);
+ } else {
+ DEBUG ("%s (%p, %u): waiting on semaphore forever...",
+ __func__, handle, timeout);
+ ret = MONO_SEM_WAIT_ALERTABLE (&mp->exit_sem, alertable);
+ }
- if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) {
- DEBUG ("%s (%p, %u): sem_timedwait failure: %s",
- __func__, handle, timeout, g_strerror (errno));
- /* Should we return a failure here? */
- }
+ if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) {
+ DEBUG ("%s (%p, %u): sem_timedwait failure: %s",
+ __func__, handle, timeout, g_strerror (errno));
+ /* Should we return a failure here? */
+ }
- if (ret == 0) {
- /* Success, process has exited */
- MONO_SEM_POST (&mp->exit_sem);
- break;
- }
- } else {
- /* We did not create this process, so we can't waidpid / sem_wait it.
- * We need to poll for the pid existence */
- DEBUG ("%s (%p, %u): polling on pid...", __func__, handle, timeout);
- if (!is_pid_valid (pid)) {
- /* Success, process has exited */
- break;
- }
+ if (ret == 0) {
+ /* Success, process has exited */
+ MONO_SEM_POST (&mp->exit_sem);
+ break;
}
if (timeout == 0) {
DEBUG ("%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout);
return WAIT_TIMEOUT;
}
-
- if (spin) {
- /* "timeout - (now - start)" will not underflow, since timeout is always >=0,
- * and we passed the check just above */
- _wapi_handle_spin (MIN (100, timeout - (now - start)));
- }
- if (alertable && _wapi_thread_apc_pending (current_thread)) {
+ if (alertable && _wapi_thread_cur_apc_pending ()) {
DEBUG ("%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
return WAIT_IO_COMPLETION;
}
g_assert (ret == 0);
status = mp ? mp->status : 0;
- if (WIFSIGNALED (status)) {
+ if (WIFSIGNALED (status))
process_handle->exitstatus = 128 + WTERMSIG (status);
- } else {
+ else
process_handle->exitstatus = WEXITSTATUS (status);
- }
_wapi_time_t_to_filetime (time (NULL), &process_handle->exit_time);
process_handle->exited = TRUE;
DEBUG ("%s (%p, %u): Setting pid %d signalled, exit status %d",
__func__, handle, timeout, process_handle->id, process_handle->exitstatus);
- _wapi_shared_handle_set_signal_state (handle, TRUE);
+ _wapi_handle_set_signal_state (handle, TRUE, TRUE);
_wapi_handle_unlock_shared_handles ();