[io-layer] Extract error (#4279)
[mono.git] / mono / metadata / w32process-unix.c
index e81b50a1acfebfd7e4ec759ecb0068639626b606..4b463886f7b067b6e9df464932cdb0e6ff41d766 100644 (file)
@@ -49,6 +49,7 @@
 #include <mono/metadata/w32process.h>
 #include <mono/metadata/w32process-internals.h>
 #include <mono/metadata/w32process-unix-internals.h>
+#include <mono/metadata/w32error.h>
 #include <mono/metadata/class.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/object.h>
@@ -56,7 +57,6 @@
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/exception.h>
-#include <mono/io-layer/io-layer.h>
 #include <mono/metadata/w32handle.h>
 #include <mono/metadata/w32file.h>
 #include <mono/utils/mono-membar.h>
@@ -70,6 +70,7 @@
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/strenc.h>
 #include <mono/utils/mono-io-portability.h>
+#include <mono/utils/w32api.h>
 
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 242
@@ -554,6 +555,7 @@ static gchar *cli_launcher;
 static Process *processes;
 static mono_mutex_t processes_mutex;
 
+static pid_t current_pid;
 static gpointer current_process;
 
 static const gunichar2 utf16_space_bytes [2] = { 0x20, 0 };
@@ -844,8 +846,10 @@ mono_w32process_init (void)
        mono_w32handle_register_capabilities (MONO_W32HANDLE_PROCESS,
                (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SPECIAL_WAIT));
 
+       current_pid = getpid ();
+
        memset (&process_handle, 0, sizeof (process_handle));
-       process_handle.pid = wapi_getpid ();
+       process_handle.pid = current_pid;
        process_set_defaults (&process_handle);
        process_set_name (&process_handle);
 
@@ -943,7 +947,7 @@ mono_w32process_get_pid (gpointer handle)
 
        res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
        if (!res) {
-               SetLastError (ERROR_INVALID_HANDLE);
+               mono_w32error_set_last (ERROR_INVALID_HANDLE);
                return 0;
        }
 
@@ -1014,7 +1018,7 @@ ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find pid %d", __func__, pid);
 
-       SetLastError (ERROR_PROC_NOT_FOUND);
+       mono_w32error_set_last (ERROR_PROC_NOT_FOUND);
        return NULL;
 }
 
@@ -1633,7 +1637,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL",
                                   __func__);
 
-                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       mono_w32error_set_last (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
                }
 
@@ -1645,7 +1649,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                if (args == NULL) {
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
 
-                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       mono_w32error_set_last (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
                }
        }
@@ -1655,7 +1659,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                if (dir == NULL) {
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
 
-                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       mono_w32error_set_last (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
                }
 
@@ -1686,7 +1690,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
                                           __func__, prog);
                                g_free (unquoted);
-                               SetLastError (ERROR_FILE_NOT_FOUND);
+                               mono_w32error_set_last (ERROR_FILE_NOT_FOUND);
                                goto free_strings;
                        }
                } else {
@@ -1703,7 +1707,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
                                           __func__, prog);
                                g_free (unquoted);
-                               SetLastError (ERROR_FILE_NOT_FOUND);
+                               mono_w32error_set_last (ERROR_FILE_NOT_FOUND);
                                goto free_strings;
                        }
                }
@@ -1767,7 +1771,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                        /* Give up */
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find what to exec", __func__);
 
-                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       mono_w32error_set_last (ERROR_PATH_NOT_FOUND);
                        goto free_strings;
                }
 
@@ -1794,7 +1798,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
                                           __func__, token);
                                g_free (token);
-                               SetLastError (ERROR_FILE_NOT_FOUND);
+                               mono_w32error_set_last (ERROR_FILE_NOT_FOUND);
                                goto free_strings;
                        }
                } else {
@@ -1821,7 +1825,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s", __func__, token);
 
                                        g_free (token);
-                                       SetLastError (ERROR_FILE_NOT_FOUND);
+                                       mono_w32error_set_last (ERROR_FILE_NOT_FOUND);
                                        goto free_strings;
                                }
                        }
@@ -1860,7 +1864,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
        } else {
                if (!is_executable (prog)) {
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Executable permisson not set on %s", __func__, prog);
-                       SetLastError (ERROR_ACCESS_DENIED);
+                       mono_w32error_set_last (ERROR_ACCESS_DENIED);
                        goto free_strings;
                }
        }
@@ -1956,7 +1960,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
 
        switch (pid = fork ()) {
        case -1: /* Error */ {
-               SetLastError (ERROR_OUTOFMEMORY);
+               mono_w32error_set_last (ERROR_OUTOFMEMORY);
                ret = FALSE;
                break;
        }
@@ -2027,7 +2031,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
                        mono_os_sem_destroy (&process->exit_sem);
                        g_free (process);
 
-                       SetLastError (ERROR_OUTOFMEMORY);
+                       mono_w32error_set_last (ERROR_OUTOFMEMORY);
                        ret = FALSE;
                        break;
                }
@@ -2086,7 +2090,7 @@ free_strings:
 
        return ret;
 #else
-       SetLastError (ERROR_NOT_SUPPORTED);
+       mono_w32error_set_last (ERROR_NOT_SUPPORTED);
        return FALSE;
 #endif // defined (HAVE_FORK) && defined (HAVE_EXECVE)
 }
@@ -2118,14 +2122,14 @@ ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStar
         */
        args = utf16_concat (utf16_quote, lpFile, utf16_quote, lpParameters == NULL ? NULL : utf16_space, lpParameters, NULL);
        if (args == NULL) {
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                ret = FALSE;
                goto done;
        }
        ret = process_create (NULL, args, lpDirectory, NULL, process_info);
        g_free (args);
 
-       if (!ret && GetLastError () == ERROR_OUTOFMEMORY)
+       if (!ret && mono_w32error_get_last () == ERROR_OUTOFMEMORY)
                goto done;
 
        if (!ret) {
@@ -2175,26 +2179,26 @@ ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStar
                args = utf16_concat (handler_utf16, utf16_space, utf16_quote, lpFile, utf16_quote,
                        lpParameters == NULL ? NULL : utf16_space, lpParameters, NULL);
                if (args == NULL) {
-                       SetLastError (ERROR_INVALID_DATA);
+                       mono_w32error_set_last (ERROR_INVALID_DATA);
                        ret = FALSE;
                        goto done;
                }
                ret = process_create (NULL, args, lpDirectory, NULL, process_info);
                g_free (args);
                if (!ret) {
-                       if (GetLastError () != ERROR_OUTOFMEMORY)
-                               SetLastError (ERROR_INVALID_DATA);
+                       if (mono_w32error_get_last () != ERROR_OUTOFMEMORY)
+                               mono_w32error_set_last (ERROR_INVALID_DATA);
                        ret = FALSE;
                        goto done;
                }
                /* Shell exec should not return a process handle when it spawned a GUI thing, like a browser. */
-               CloseHandle (process_info->process_handle);
+               mono_w32handle_close (process_info->process_handle);
                process_info->process_handle = NULL;
        }
 
 done:
        if (ret == FALSE) {
-               process_info->pid = -GetLastError ();
+               process_info->pid = -mono_w32error_get_last ();
        } else {
                process_info->thread_handle = NULL;
 #if !defined(MONO_CROSS_COMPILE)
@@ -2290,7 +2294,7 @@ ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoW32ProcessStart
                g_free (shell_path);
 
        if (!ret)
-               process_info->pid = -GetLastError ();
+               process_info->pid = -mono_w32error_get_last ();
 
        return ret;
 }
@@ -2368,7 +2372,7 @@ ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gin
                return FALSE;
        }
 
-       if (process_handle->pid == wapi_getpid ()) {
+       if (process_handle->pid == current_pid) {
                *exitcode = STILL_ACTIVE;
                return TRUE;
        }
@@ -2388,7 +2392,7 @@ ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
 {
        if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
                return TRUE;
-       return CloseHandle (handle);
+       return mono_w32handle_close (handle);
 }
 
 MonoBoolean
@@ -2408,7 +2412,7 @@ ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint3
                res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
                if (!res) {
                        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
-                       SetLastError (ERROR_INVALID_HANDLE);
+                       mono_w32error_set_last (ERROR_INVALID_HANDLE);
                        return FALSE;
                }
 
@@ -2420,10 +2424,10 @@ ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint3
                return TRUE;
 
        switch (errno) {
-       case EINVAL: SetLastError (ERROR_INVALID_PARAMETER); break;
-       case EPERM:  SetLastError (ERROR_ACCESS_DENIED);     break;
-       case ESRCH:  SetLastError (ERROR_PROC_NOT_FOUND);    break;
-       default:     SetLastError (ERROR_GEN_FAILURE);       break;
+       case EINVAL: mono_w32error_set_last (ERROR_INVALID_PARAMETER); break;
+       case EPERM:  mono_w32error_set_last (ERROR_ACCESS_DENIED);     break;
+       case ESRCH:  mono_w32error_set_last (ERROR_PROC_NOT_FOUND);    break;
+       default:     mono_w32error_set_last (ERROR_GEN_FAILURE);       break;
        }
 
        return FALSE;
@@ -2491,7 +2495,7 @@ ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
 
                res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
                if (!res) {
-                       SetLastError (ERROR_INVALID_HANDLE);
+                       mono_w32error_set_last (ERROR_INVALID_HANDLE);
                        return 0;
                }
 
@@ -2504,13 +2508,13 @@ ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
                switch (errno) {
                case EPERM:
                case EACCES:
-                       SetLastError (ERROR_ACCESS_DENIED);
+                       mono_w32error_set_last (ERROR_ACCESS_DENIED);
                        break;
                case ESRCH:
-                       SetLastError (ERROR_PROC_NOT_FOUND);
+                       mono_w32error_set_last (ERROR_PROC_NOT_FOUND);
                        break;
                default:
-                       SetLastError (ERROR_GEN_FAILURE);
+                       mono_w32error_set_last (ERROR_GEN_FAILURE);
                }
                return 0;
        }
@@ -2530,7 +2534,7 @@ ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
 
        return MONO_W32PROCESS_PRIORITY_CLASS_NORMAL;
 #else
-       SetLastError (ERROR_NOT_SUPPORTED);
+       mono_w32error_set_last (ERROR_NOT_SUPPORTED);
        return 0;
 #endif
 }
@@ -2552,7 +2556,7 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3
 
                res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
                if (!res) {
-                       SetLastError (ERROR_INVALID_HANDLE);
+                       mono_w32error_set_last (ERROR_INVALID_HANDLE);
                        return FALSE;
                }
 
@@ -2579,7 +2583,7 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3
                prio = -20;
                break;
        default:
-               SetLastError (ERROR_INVALID_PARAMETER);
+               mono_w32error_set_last (ERROR_INVALID_PARAMETER);
                return FALSE;
        }
 
@@ -2588,19 +2592,19 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3
                switch (errno) {
                case EPERM:
                case EACCES:
-                       SetLastError (ERROR_ACCESS_DENIED);
+                       mono_w32error_set_last (ERROR_ACCESS_DENIED);
                        break;
                case ESRCH:
-                       SetLastError (ERROR_PROC_NOT_FOUND);
+                       mono_w32error_set_last (ERROR_PROC_NOT_FOUND);
                        break;
                default:
-                       SetLastError (ERROR_GEN_FAILURE);
+                       mono_w32error_set_last (ERROR_GEN_FAILURE);
                }
        }
 
        return ret == 0;
 #else
-       SetLastError (ERROR_NOT_SUPPORTED);
+       mono_w32error_set_last (ERROR_NOT_SUPPORTED);
        return FALSE;
 #endif
 }
@@ -2798,14 +2802,14 @@ find_pe_file_resources32 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad dos signature 0x%x", __func__, dos_header->e_magic);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
        if (map_size < sizeof(IMAGE_NT_HEADERS32) + GUINT32_FROM_LE (dos_header->e_lfanew)) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File is too small: %d", __func__, map_size);
 
-               SetLastError (ERROR_BAD_LENGTH);
+               mono_w32error_set_last (ERROR_BAD_LENGTH);
                return(NULL);
        }
 
@@ -2813,7 +2817,7 @@ find_pe_file_resources32 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad NT signature 0x%x", __func__, nt_headers->Signature);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
@@ -2827,7 +2831,7 @@ find_pe_file_resources32 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (resource_rva == 0) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No resources in file!", __func__);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
@@ -2835,7 +2839,7 @@ find_pe_file_resources32 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (resource_dir == NULL) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find resource directory", __func__);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
@@ -2870,14 +2874,14 @@ find_pe_file_resources64 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad dos signature 0x%x", __func__, dos_header->e_magic);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
        if (map_size < sizeof(IMAGE_NT_HEADERS64) + GUINT32_FROM_LE (dos_header->e_lfanew)) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File is too small: %d", __func__, map_size);
 
-               SetLastError (ERROR_BAD_LENGTH);
+               mono_w32error_set_last (ERROR_BAD_LENGTH);
                return(NULL);
        }
 
@@ -2886,7 +2890,7 @@ find_pe_file_resources64 (gpointer file_map, guint32 map_size, guint32 res_id, g
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Bad NT signature 0x%x", __func__,
                           nt_headers->Signature);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
@@ -2900,7 +2904,7 @@ find_pe_file_resources64 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (resource_rva == 0) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No resources in file!", __func__);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
@@ -2908,7 +2912,7 @@ find_pe_file_resources64 (gpointer file_map, guint32 map_size, guint32 res_id, g
        if (resource_dir == NULL) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find resource directory", __func__);
 
-               SetLastError (ERROR_INVALID_DATA);
+               mono_w32error_set_last (ERROR_INVALID_DATA);
                return(NULL);
        }
 
@@ -2959,7 +2963,7 @@ map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
        if (filename_ext == NULL) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
 
-               SetLastError (ERROR_INVALID_NAME);
+               mono_w32error_set_last (ERROR_INVALID_NAME);
                return(NULL);
        }
 
@@ -2978,7 +2982,7 @@ map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
 
                        g_free (filename_ext);
 
-                       SetLastError (_wapi_get_win32_file_error (errno));
+                       mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
                        return NULL;
                }
 
@@ -2989,7 +2993,7 @@ map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
                        g_free (filename_ext);
                        g_free (located_filename);
 
-                       SetLastError (_wapi_get_win32_file_error (errno));
+                       mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
                        return NULL;
                }
 
@@ -2999,7 +3003,7 @@ map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
        if (fstat (fd, &statbuf) == -1) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error stat()ing file %s: %s", __func__, filename_ext, strerror (errno));
 
-               SetLastError (_wapi_get_win32_file_error (errno));
+               mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
                g_free (filename_ext);
                close (fd);
                return(NULL);
@@ -3010,7 +3014,7 @@ map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
        if (statbuf.st_size < sizeof(IMAGE_DOS_HEADER)) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File %s is too small: %lld", __func__, filename_ext, statbuf.st_size);
 
-               SetLastError (ERROR_BAD_LENGTH);
+               mono_w32error_set_last (ERROR_BAD_LENGTH);
                g_free (filename_ext);
                close (fd);
                return(NULL);
@@ -3020,7 +3024,7 @@ map_pe_file (gunichar2 *filename, gint32 *map_size, void **handle)
        if (file_map == NULL) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error mmap()int file %s: %s", __func__, filename_ext, strerror (errno));
 
-               SetLastError (_wapi_get_win32_file_error (errno));
+               mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
                g_free (filename_ext);
                close (fd);
                return(NULL);