#include <unistd.h>
#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/unicode.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/mono-mutex.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
+#include <mono/utils/strenc.h>
/* The process' environment strings */
extern char **environ;
WapiStartupInfo *startup,
WapiProcessInformation *process_info)
{
- gchar *cmd=NULL, *prog, *full_prog, *args=NULL, *args_after_prog=NULL, *dir=NULL;
+ gchar *cmd=NULL, *prog = NULL, *full_prog = NULL, *args=NULL, *args_after_prog=NULL, *dir=NULL;
guint32 env=0, stored_dir=0, stored_prog=0, i;
gboolean ret=FALSE;
gpointer stdin_handle, stdout_handle, stderr_handle;
* so crap, with an API like this :-(
*/
if(appname!=NULL) {
- cmd=_wapi_unicode_to_utf8 (appname);
+ cmd=mono_unicode_to_external (appname);
if(cmd==NULL) {
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": unicode conversion returned NULL");
#endif
+ SetLastError(ERROR_PATH_NOT_FOUND);
goto cleanup;
}
}
if(cmdline!=NULL) {
- args=_wapi_unicode_to_utf8 (cmdline);
+ args=mono_unicode_to_external (cmdline);
if(args==NULL) {
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": unicode conversion returned NULL");
#endif
+ SetLastError(ERROR_PATH_NOT_FOUND);
goto cleanup;
}
-
- /* Turn all the slashes round the right way */
- for(i=0; i<strlen (args); i++) {
- if(args[i]=='\\') {
- args[i]='/';
- }
- }
}
if(cwd!=NULL) {
- dir=_wapi_unicode_to_utf8 (cwd);
+ dir=mono_unicode_to_external (cwd);
if(dir==NULL) {
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": unicode conversion returned NULL");
#endif
+ SetLastError(ERROR_PATH_NOT_FOUND);
goto cleanup;
}
*/
if(new_environ!=NULL) {
gchar **strings;
- guint32 count;
+ guint32 count=0;
gunichar2 *new_environp;
/* Count the number of strings */
strings=g_new0 (gchar *, count);
/* Copy each environ string into 'strings' turning it
- * into utf8 at the same time
+ * into utf8 (or the requested encoding) at the same
+ * time
*/
count=0;
for(new_environp=(gunichar2 *)new_environ; *new_environp;
new_environp++) {
- strings[count]=g_utf16_to_utf8 (new_environp, -1, NULL,
- NULL, NULL);
+ strings[count]=mono_unicode_to_external (new_environp);
count++;
while(*new_environp) {
new_environp++;
if(cmd[0]=='/') {
/* Assume full path given */
prog=g_strdup (cmd);
+
+ /* Executable existing ? */
+ if(access (prog, X_OK)!=0) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Couldn't find executable %s", prog);
+#endif
+ g_free (prog);
+ SetLastError (ERROR_FILE_NOT_FOUND);
+ goto cleanup;
+ }
} else {
/* Search for file named by cmd in the current
* directory
for(i=0; args[i]!='\0'; i++) {
if(g_ascii_isspace (args[i])) {
token=g_strndup (args, i);
- args_after_prog=args+i;
+ args_after_prog=args+i+1;
break;
}
}
": Couldn't find what to exec");
#endif
+ SetLastError(ERROR_PATH_NOT_FOUND);
goto cleanup;
}
+ /* Turn all the slashes round the right way. Only for the prg. name */
+ for(i=0; i < strlen (token); i++) {
+ if (token[i]=='\\') {
+ token[i]='/';
+ }
+ }
+
if(g_ascii_isalpha (token[0]) && (token[1]==':')) {
/* Strip off the drive letter. I can't
* believe that CP/M holdover is still
if(token[0]=='/') {
/* Assume full path given */
prog=g_strdup (token);
+
+ /* Executable existing ? */
+ if(access (prog, X_OK)!=0) {
+ g_free (prog);
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Couldn't find executable %s", token);
+#endif
+ g_free (token);
+ SetLastError (ERROR_FILE_NOT_FOUND);
+ goto cleanup;
+ }
+
} else {
char *curdir=g_get_current_dir ();
#endif
g_free (token);
+ SetLastError (ERROR_FILE_NOT_FOUND);
goto cleanup;
}
}
process_info->hThread=thread_handle;
process_info->dwProcessId=pid;
process_info->dwThreadId=tid;
+ } else if(ret==FALSE) {
+ /* FIXME: work out a better error code
+ */
+ SetLastError(ERROR_PATH_NOT_FOUND);
}
cleanup:
return(ret);
}
-
-static gboolean process_compare (gpointer handle, gpointer user_data)
+
+static void process_set_name (struct _WapiHandle_process *process_handle)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
- pid_t pid;
+ gchar *progname, *utf8_progname, *slash;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up process handle %p", handle);
- return(FALSE);
- }
+ progname=g_get_prgname ();
+ utf8_progname=mono_utf8_from_external (progname);
- pid=GPOINTER_TO_UINT (user_data);
- if(process_handle->id==pid) {
- return(TRUE);
- } else {
- return(FALSE);
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": using [%s] as prog name",
+ progname);
+#endif
+
+ if(utf8_progname!=NULL) {
+ slash=strrchr (utf8_progname, '/');
+ if(slash!=NULL) {
+ process_handle->proc_name=_wapi_handle_scratch_store (slash+1, strlen (slash+1));
+ } else {
+ process_handle->proc_name=_wapi_handle_scratch_store (utf8_progname, strlen (utf8_progname));
+ }
+
+ g_free (utf8_progname);
}
}
-
+
static void process_set_current (void)
{
struct _WapiHandle_process *process_handle;
gboolean ok;
pid_t pid=getpid ();
+ char *handle_env;
- current_process=_wapi_search_handle (WAPI_HANDLE_PROCESS,
- process_compare,
- GUINT_TO_POINTER (pid),
- (gpointer *)&process_handle,
- NULL);
- if(current_process==0) {
- gchar *progname, *slash;
-
+ handle_env=getenv ("_WAPI_PROCESS_HANDLE");
+ if(handle_env==NULL) {
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": Need to create my own process handle");
/* These seem to be the defaults on w2k */
process_handle->min_working_set=204800;
process_handle->max_working_set=1413120;
+
+ process_set_name (process_handle);
+
+ /* Make sure the new handle has a reference so it wont go away
+ * until this process exits
+ */
+ _wapi_handle_ref (current_process);
+ } else {
+ guchar *procname;
- progname=g_get_prgname ();
+ current_process=GUINT_TO_POINTER (atoi (handle_env));
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": using [%s] as prog name",
- progname);
+ g_message (G_GNUC_PRETTY_FUNCTION
+ ": Found my process handle: %p", current_process);
#endif
- if(progname!=NULL) {
- slash=strrchr (progname, '/');
- if(slash!=NULL) {
- process_handle->proc_name=_wapi_handle_scratch_store (slash+1, strlen (slash+1));
- } else {
- process_handle->proc_name=_wapi_handle_scratch_store (progname, strlen (progname));
- }
+ ok=_wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS,
+ (gpointer *)&process_handle, NULL);
+ if(ok==FALSE) {
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ ": error looking up process handle %p",
+ current_process);
+ return;
}
- /* Make sure the new handle has a reference so it wont go away
- * until this process exits
- */
- _wapi_handle_ref (current_process);
- } else {
+ procname=_wapi_handle_scratch_lookup (process_handle->proc_name);
+ if(procname!=NULL) {
+ if(!strcmp (procname, "mono")) {
+ /* Set a better process name */
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Setting better process name");
+#endif
+
+ _wapi_handle_scratch_delete (process_handle->proc_name);
+ process_set_name (process_handle);
+ } else {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Found my process handle");
+ g_message (G_GNUC_PRETTY_FUNCTION
+ ": Leaving process name: %s",
+ procname);
#endif
+ }
+
+ g_free (procname);
+ }
}
}
guint32 GetCurrentProcessId (void)
{
+ struct _WapiHandle_process *current_process_handle;
+ gboolean ok;
+
mono_once (&process_current_once, process_set_current);
- return(getpid ());
+ ok=_wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS,
+ (gpointer *)¤t_process_handle, NULL);
+ if(ok==FALSE) {
+ g_warning (G_GNUC_PRETTY_FUNCTION
+ ": error looking up current process handle %p",
+ 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);
+ }
+
+ return(current_process_handle->id);
}
static gboolean process_enum (gpointer handle, gpointer user_data)
#endif
pid=process_handle->id;
- procname_utf8=_wapi_handle_scratch_lookup_as_string (process_handle->proc_name);
+ procname_utf8=_wapi_handle_scratch_lookup (process_handle->proc_name);
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": Process name is [%s]",