* Author:
* Dick Porter (dick@ximian.com)
*
- * (C) 2002 Ximian, Inc.
+ * (C) 2002-2006 Novell, Inc.
*/
#include <config.h>
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
- process_wait /* special_wait */
+ process_wait, /* special_wait */
+ NULL /* prewait */
};
static mono_once_t process_current_once=MONO_ONCE_INIT;
g_message ("%s: Reaping child processes", __func__);
#endif
- _wapi_search_handle (WAPI_HANDLE_PROCESS, waitfor_pid, NULL, NULL);
+ _wapi_search_handle (WAPI_HANDLE_PROCESS, waitfor_pid, NULL, NULL,
+ FALSE);
}
/* Limitations: This can only wait for processes that are our own
return(WAIT_OBJECT_0);
}
+
+void _wapi_process_signal_self ()
+{
+ if (current_process != NULL) {
+ process_set_termination_details (current_process, 0);
+ }
+}
+
static void process_set_defaults (struct _WapiHandle_process *process_handle)
{
SetLastError (ERROR_INVALID_PARAMETER);
return (FALSE);
}
+
+ if (sei->lpFile == NULL) {
+ /* w2k returns TRUE for this, for some reason. */
+ return (TRUE);
+ }
/* Put both executable and parameters into the second argument
* to CreateProcess (), so it searches $PATH. The conversion
return (FALSE);
}
- u8params = g_utf16_to_utf8 (sei->lpParameters, -1, NULL, NULL, NULL);
- if (u8params == NULL) {
- SetLastError (ERROR_INVALID_DATA);
- g_free (u8file);
- return (FALSE);
- }
+ if (sei->lpParameters != NULL) {
+ u8params = g_utf16_to_utf8 (sei->lpParameters, -1, NULL, NULL, NULL);
+ if (u8params == NULL) {
+ SetLastError (ERROR_INVALID_DATA);
+ g_free (u8file);
+ return (FALSE);
+ }
- u8args = g_strdup_printf ("%s %s", u8file, u8params);
- if (u8args == NULL) {
- SetLastError (ERROR_INVALID_DATA);
- g_free (u8params);
- g_free (u8file);
- return (FALSE);
- }
+ u8args = g_strdup_printf ("%s %s", u8file, u8params);
+ if (u8args == NULL) {
+ SetLastError (ERROR_INVALID_DATA);
+ g_free (u8params);
+ g_free (u8file);
+ return (FALSE);
+ }
- args = g_utf8_to_utf16 (u8args, -1, NULL, NULL, NULL);
+ args = g_utf8_to_utf16 (u8args, -1, NULL, NULL, NULL);
- g_free (u8file);
- g_free (u8params);
- g_free (u8args);
-
+ g_free (u8file);
+ g_free (u8params);
+ g_free (u8args);
+ } else {
+ args = g_utf8_to_utf16 (u8file, -1, NULL, NULL, NULL);
+ }
+
if (args == NULL) {
SetLastError (ERROR_INVALID_DATA);
return (FALSE);
GError *gerr = NULL;
int in_fd, out_fd, err_fd;
pid_t pid;
- int lockpipe [2];
int thr_ret;
mono_once (&process_ops_once, process_ops_init);
SetLastError (ERROR_PATH_NOT_FOUND);
goto cleanup;
}
+
+ /* Hold another reference so the process has somewhere to
+ * store its exit data even if we drop this handle
+ */
+ _wapi_handle_ref (handle);
/* new_environ is a block of NULL-terminated strings, which
* is itself NULL-terminated. Of course, passing an array of
env_strings[env_count] = g_strdup_printf ("_WAPI_PROCESS_HANDLE_OFFSET=%d", ref->offset);
}
-
- pipe (lockpipe);
+
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
pid = fork ();
if (pid == -1) {
goto cleanup;
} else if (pid == 0) {
/* Child */
- char c [1];
- /* Wait for the parent to finish setting up the handle */
- close (lockpipe [1]);
- while (read (lockpipe [0], c, 1) == -1 &&
- errno == EINTR);
- close (lockpipe [0]);
+ /* Wait for the parent to finish setting up the
+ * handle. The semaphore lock is safe because the
+ * sem_undo structures of a semaphore aren't inherited
+ * across a fork ()
+ */
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
+
+ _wapi_handle_unlock_shared_handles ();
/* should we detach from the process group? */
exit (-1);
}
/* parent */
-
- thr_ret = _wapi_handle_lock_shared_handles ();
- g_assert (thr_ret == 0);
ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
(gpointer *)&process_handle_data);
process_handle_data->id = pid;
- _wapi_handle_unlock_shared_handles ();
-
- write (lockpipe [1], cmd, 1);
-
if (process_info != NULL) {
process_info->hProcess = handle;
process_info->dwProcessId = pid;
}
cleanup:
- close (lockpipe [0]);
- close (lockpipe [1]);
-
+ _wapi_handle_unlock_shared_handles ();
+
if (cmd != NULL) {
g_free (cmd);
}
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)
{
- pid_t pid = getpid ();
- char *handle_env;
+ pid_t pid = _wapi_getpid ();
+ const char *handle_env;
struct _WapiHandle_process process_handle = {0};
- handle_env = getenv ("_WAPI_PROCESS_HANDLE_OFFSET");
+ handle_env = g_getenv ("_WAPI_PROCESS_HANDLE_OFFSET");
+ g_unsetenv ("_WAPI_PROCESS_HANDLE_OFFSET");
+
if (handle_env != NULL) {
struct _WapiHandle_process *process_handlep;
guchar *procname = NULL;
current_process = _wapi_handle_new_from_offset (WAPI_HANDLE_PROCESS, atoi (handle_env), TRUE);
#ifdef DEBUG
- g_message ("%s: Found my process handle: %p (offset %d)",
- __func__, current_process, atoi (handle_env));
+ g_message ("%s: Found my process handle: %p (offset %d 0x%x)",
+ __func__, current_process, atoi (handle_env),
+ atoi (handle_env));
#endif
ok = _wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS,
(gpointer *)&process_handlep);
- if (ok == FALSE) {
- g_warning ("%s: error looking up process handle %p",
- __func__, current_process);
- return;
- }
-
- /* This test will 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 */
+ 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 */
#ifdef DEBUG
- g_message ("%s: Setting better process name",
- __func__);
+ g_message ("%s: Setting better process name", __func__);
#endif
-
- process_set_name (process_handlep);
- } else {
+
+ process_set_name (process_handlep);
+ } else {
#ifdef DEBUG
- g_message ("%s: Leaving process name: %s",
- __func__, procname);
+ g_message ("%s: Leaving process name: %s", __func__, procname);
#endif
+ }
+
+ return;
}
- return;
+ /* Wrong pid, so drop this handle and fall through to
+ * create a new one
+ */
+ _wapi_handle_unref (current_process);
}
-
- /* 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.)
+ */
+
#ifdef DEBUG
g_message ("%s: Need to create my own process handle", __func__);
#endif
return((gpointer)-1);
}
-guint32 GetCurrentProcessId (void)
+guint32 GetProcessId (gpointer handle)
{
- struct _WapiHandle_process *current_process_handle;
+ struct _WapiHandle_process *process_handle;
gboolean ok;
- mono_once (&process_current_once, process_set_current);
-
- ok=_wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS,
- (gpointer *)¤t_process_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up current process handle %p",
- __func__, current_process);
- /* No failure return is defined. PID 0 is invalid.
- * This should only be reached when something else has
- * gone badly wrong anyway.
- */
- return(0);
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
+ (gpointer *)&process_handle);
+ if (ok == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return (0);
}
- return(current_process_handle->id);
+ return (process_handle->id);
+}
+
+guint32 GetCurrentProcessId (void)
+{
+ mono_once (&process_current_once, process_set_current);
+
+ return (GetProcessId (current_process));
}
/* Returns the process id as a convenience to the functions that call this */
mono_once (&process_current_once, process_set_current);
_wapi_search_handle (WAPI_HANDLE_PROCESS, process_enum, processes,
- NULL);
+ NULL, TRUE);
fit=len/sizeof(guint32);
for (i = 0, j = 0; j < fit && i < processes->len; i++) {
handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
process_open_compare,
- GUINT_TO_POINTER (pid), NULL);
+ GUINT_TO_POINTER (pid), NULL, TRUE);
if (handle == 0) {
#ifdef DEBUG
g_message ("%s: Can't find pid %d", __func__, pid);