[runtime] Use coop handles for System.Environment icalls
authorAleksey Kliger <aleksey@xamarin.com>
Mon, 1 May 2017 18:47:24 +0000 (14:47 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Thu, 4 May 2017 16:00:31 +0000 (12:00 -0400)
- get_UserName
- get_NewLine
- get_MachineName
- GetWindowsFolderPath
- GetOSVersionString

MonoError-ize mono_icall_get_environment_variable_names

mono/metadata/environment.c
mono/metadata/icall-def.h
mono/metadata/icall-internals.h
mono/metadata/icall-windows-uwp.c
mono/metadata/icall-windows.c
mono/metadata/icall.c
mono/metadata/security.h

index 2ccf0fe7217eb1ba5e55bd1524f219565a205cf2..b7001b57ac5664ceae8e509c920c273cc5f83ed6 100644 (file)
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/handle.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/w32api.h>
 
-extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
+extern MonoStringHandle ves_icall_System_Environment_GetOSVersionString (MonoError *error);
 
 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
 #include <sys/utsname.h>
@@ -47,9 +48,10 @@ mono_environment_exitcode_set (gint32 value)
 }
 
 /* note: we better manipulate the string in managed code (easier and safer) */
-MonoString*
-ves_icall_System_Environment_GetOSVersionString (void)
+MonoStringHandle
+ves_icall_System_Environment_GetOSVersionString (MonoError *error)
 {
+       error_init (error);
 #ifdef HOST_WIN32
        OSVERSIONINFOEX verinfo;
 
@@ -63,15 +65,15 @@ ves_icall_System_Environment_GetOSVersionString (void)
                                 verinfo.dwMinorVersion,
                                 verinfo.dwBuildNumber,
                                 verinfo.wServicePackMajor << 16);
-               return mono_string_new (mono_domain_get (), version);
+               return mono_string_new_handle (mono_domain_get (), version, error);
        }
 #elif defined(HAVE_SYS_UTSNAME_H)
        struct utsname name;
 
        if (uname (&name) >= 0) {
-               return mono_string_new (mono_domain_get (), name.release);
+               return mono_string_new_handle (mono_domain_get (), name.release, error);
        }
 #endif
-       return mono_string_new (mono_domain_get (), "0.0.0.0");
+       return mono_string_new_handle (mono_domain_get (), "0.0.0.0", error);
 }
 
index 84b6a4d24fbf2a1428cb377f9bc3dbeebf43a1eb..9ffbd495e4df58c9d99b00101f5af34ed4dcf174 100644 (file)
@@ -268,18 +268,18 @@ ICALL(ENV_3, "GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvi
 ICALL(ENV_31, "GetIs64BitOperatingSystem", ves_icall_System_Environment_GetIs64BitOperatingSystem)
 ICALL(ENV_4, "GetLogicalDrivesInternal", ves_icall_System_Environment_GetLogicalDrives )
 ICALL(ENV_5, "GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path)
-ICALL(ENV_51, "GetNewLine", ves_icall_System_Environment_get_NewLine)
-ICALL(ENV_6, "GetOSVersionString", ves_icall_System_Environment_GetOSVersionString)
+HANDLES(ICALL(ENV_51, "GetNewLine", ves_icall_System_Environment_get_NewLine))
+HANDLES(ICALL(ENV_6, "GetOSVersionString", ves_icall_System_Environment_GetOSVersionString))
 ICALL(ENV_6a, "GetPageSize", mono_pagesize)
-ICALL(ENV_7, "GetWindowsFolderPath", ves_icall_System_Environment_GetWindowsFolderPath)
+HANDLES(ICALL(ENV_7, "GetWindowsFolderPath", ves_icall_System_Environment_GetWindowsFolderPath))
 ICALL(ENV_8, "InternalSetEnvironmentVariable", ves_icall_System_Environment_InternalSetEnvironmentVariable)
 ICALL(ENV_9, "get_ExitCode", mono_environment_exitcode_get)
 ICALL(ENV_10, "get_HasShutdownStarted", ves_icall_System_Environment_get_HasShutdownStarted)
-ICALL(ENV_11, "get_MachineName", ves_icall_System_Environment_get_MachineName)
+HANDLES(ICALL(ENV_11, "get_MachineName", ves_icall_System_Environment_get_MachineName))
 ICALL(ENV_13, "get_Platform", ves_icall_System_Environment_get_Platform)
 ICALL(ENV_14, "get_ProcessorCount", mono_cpu_count)
 ICALL(ENV_15, "get_TickCount", ves_icall_System_Environment_get_TickCount)
-ICALL(ENV_16, "get_UserName", ves_icall_System_Environment_get_UserName)
+HANDLES(ICALL(ENV_16, "get_UserName", ves_icall_System_Environment_get_UserName))
 HANDLES(ICALL(ENV_16b, "get_bundled_machine_config", ves_icall_System_Environment_get_bundled_machine_config))
 ICALL(ENV_16m, "internalBroadcastSettingChange", ves_icall_System_Environment_BroadcastSettingChange)
 HANDLES(ICALL(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Environment_GetEnvironmentVariable_native))
index 62af7edbdf5a6a7f9b809f5cc0af855b3422f679..60cca8316b0ae31da8f794ecc075c71558cdae13 100644 (file)
@@ -23,26 +23,26 @@ mono_icall_get_file_path_prefix (const gchar *path);
 gpointer
 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module);
 
-MonoString *
-mono_icall_get_machine_name (void);
+MonoStringHandle
+mono_icall_get_machine_name (MonoError *error);
 
 int
 mono_icall_get_platform (void);
 
-MonoString *
-mono_icall_get_new_line (void);
+MonoStringHandle
+mono_icall_get_new_line (MonoError *error);
 
 MonoBoolean
 mono_icall_is_64bit_os (void);
 
 MonoArray *
-mono_icall_get_environment_variable_names (void);
+mono_icall_get_environment_variable_names (MonoError *error);
 
 void
 mono_icall_set_environment_variable (MonoString *name, MonoString *value);
 
-MonoString *
-mono_icall_get_windows_folder_path (int folder);
+MonoStringHandle
+mono_icall_get_windows_folder_path (int folder, MonoError *error);
 
 void
 mono_icall_broadcast_setting_change (void);
index 92b8d76e089566d24afdbac215f99b5f4e3fc659..2708e90e26e5b2d2faa2c0f53e1606de13f66efe 100644 (file)
 #include <windows.h>
 #include "mono/metadata/icall-windows-internals.h"
 
-MonoString *
-mono_icall_get_machine_name (void)
+MonoStringHandle
+mono_icall_get_machine_name (MonoError *error)
 {
        g_unsupported_api ("GetComputerName");
-       return mono_string_new (mono_domain_get (), "mono");
+       return mono_string_new_handle (mono_domain_get (), "mono", error);
 }
 
-MonoString *
-mono_icall_get_windows_folder_path (int folder)
+MonoStringHandle
+mono_icall_get_windows_folder_path (int folder, MonoError *error)
 {
+       error_init (error);
        g_unsupported_api ("SHGetFolderPath");
-       return mono_string_new (mono_domain_get (), "");
+       return mono_string_new_handle (mono_domain_get (), "", error);
 }
 
 MonoArray *
index c0b1d314d9189e72cb8534913a59edb9f0dc792d..21a759157c08641bc2d5cfdcac05f8ebd6c738ca 100644 (file)
@@ -46,22 +46,21 @@ mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
 }
 
 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-MonoString *
-mono_icall_get_machine_name (void)
+MonoStringHandle
+mono_icall_get_machine_name (MonoError *error)
 {
        gunichar2 *buf;
        guint32 len;
-       MonoString *result;
+       MonoStringHandle result;
 
        len = MAX_COMPUTERNAME_LENGTH + 1;
        buf = g_new (gunichar2, len);
 
        result = NULL;
        if (GetComputerName (buf, (PDWORD) &len)) {
-               MonoError error;
-               result = mono_string_new_utf16_checked (mono_domain_get (), buf, len, &error);
-               mono_error_set_pending_exception (&error);
-       }
+               result = mono_string_new_utf16_handle (mono_domain_get (), buf, len, error);
+       } else
+               result = MONO_HANDLE_NEW (MonoString, NULL);
 
        g_free (buf);
        return result;
@@ -75,10 +74,11 @@ mono_icall_get_platform (void)
        return 2;
 }
 
-MonoString *
-mono_icall_get_new_line (void)
+MonoStringHandle
+mono_icall_get_new_line (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), "\r\n");
+       error_init (error);
+       return mono_string_new_handle (mono_domain_get (), "\r\n", error);
 }
 
 MonoBoolean
@@ -96,9 +96,8 @@ mono_icall_is_64bit_os (void)
 }
 
 MonoArray *
-mono_icall_get_environment_variable_names (void)
+mono_icall_get_environment_variable_names (MonoError *error)
 {
-       MonoError error;
        MonoArray *names;
        MonoDomain *domain;
        MonoString *str;
@@ -107,6 +106,7 @@ mono_icall_get_environment_variable_names (void)
        WCHAR* equal_str;
        int n = 0;
 
+       error_init (error);
        env_strings = GetEnvironmentStrings();
 
        if (env_strings) {
@@ -122,9 +122,8 @@ mono_icall_get_environment_variable_names (void)
        }
 
        domain = mono_domain_get ();
-       names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       names = mono_array_new_checked (domain, mono_defaults.string_class, n, error);
+       return_val_if_nok (error, NULL);
 
        if (env_strings) {
                n = 0;
@@ -134,9 +133,9 @@ mono_icall_get_environment_variable_names (void)
                        if (*env_string != '=') {
                                equal_str = wcschr(env_string, '=');
                                g_assert(equal_str);
-                               str = mono_string_new_utf16_checked (domain, env_string, (gint32)(equal_str - env_string), &error);
-                               if (mono_error_set_pending_exception (&error))
-                                       return NULL;
+                               str = mono_string_new_utf16_checked (domain, env_string, (gint32)(equal_str - env_string), error);
+                               if (!is_ok (error))
+                                       goto cleanup;
 
                                mono_array_setref (names, n, str);
                                n++;
@@ -146,9 +145,13 @@ mono_icall_get_environment_variable_names (void)
                        env_string++;
                }
 
-               FreeEnvironmentStrings (env_strings);
        }
 
+cleanup:
+       if (env_strings)
+               FreeEnvironmentStrings (env_strings);
+       if (!is_ok (error))
+               return NULL;
        return names;
 }
 
@@ -173,9 +176,10 @@ mono_icall_set_environment_variable (MonoString *name, MonoString *value)
 }
 
 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-MonoString *
-mono_icall_get_windows_folder_path (int folder)
+MonoStringHandle
+mono_icall_get_windows_folder_path (int folder, MonoError *error)
 {
+       error_init (error);
        #ifndef CSIDL_FLAG_CREATE
                #define CSIDL_FLAG_CREATE       0x8000
        #endif
@@ -186,12 +190,9 @@ mono_icall_get_windows_folder_path (int folder)
                int len = 0;
                while (path [len])
                        ++ len;
-               MonoError error;
-               MonoString *res = mono_string_new_utf16_checked (mono_domain_get (), path, len, &error);
-               mono_error_set_pending_exception (&error);
-               return res;
+               return mono_string_new_utf16_handle (mono_domain_get (), path, len, error);
        }
-       return mono_string_new (mono_domain_get (), "");
+       return mono_string_new_handle (mono_domain_get (), "", error);
 }
 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
index 9e1c7903d7899d3bc32fd9bdacb06e389c81a5ad..2bbde0097c6a0e190c649d4aa9f6e019cc17d688 100644 (file)
 #include <sys/utsname.h>
 #endif
 
-extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
+extern MonoStringHandle ves_icall_System_Environment_GetOSVersionString (MonoError *error);
 
 ICALL_EXPORT MonoReflectionAssemblyHandle ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error);
 
@@ -6415,19 +6415,21 @@ ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
 
 /* System.Environment */
 
-MonoString*
-ves_icall_System_Environment_get_UserName (void)
+MonoStringHandle
+ves_icall_System_Environment_get_UserName (MonoError *error)
 {
+       error_init (error);
        /* using glib is more portable */
-       return mono_string_new (mono_domain_get (), g_get_user_name ());
+       return mono_string_new_handle (mono_domain_get (), g_get_user_name (), error);
 }
 
 #ifndef HOST_WIN32
-static MonoString *
-mono_icall_get_machine_name (void)
+static MonoStringHandle
+mono_icall_get_machine_name (MonoError *error)
 {
+       error_init (error);
 #if !defined(DISABLE_SOCKETS)
-       MonoString *result;
+       MonoStringHandle result;
        char *buf;
        int n;
 #if defined _SC_HOST_NAME_MAX
@@ -6439,22 +6441,23 @@ mono_icall_get_machine_name (void)
        
        if (gethostname (buf, n) == 0){
                buf [n] = 0;
-               result = mono_string_new (mono_domain_get (), buf);
+               result = mono_string_new_handle (mono_domain_get (), buf, error);
        } else
-               result = NULL;
+               result = MONO_HANDLE_CAST (MonoString, NULL_HANDLE);
        g_free (buf);
        
        return result;
 #else
-       return mono_string_new (mono_domain_get (), "mono");
+       return mono_string_new_handle (mono_domain_get (), "mono", error);
 #endif
 }
 #endif /* !HOST_WIN32 */
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_get_MachineName (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_get_MachineName (MonoError *error)
 {
-       return mono_icall_get_machine_name ();
+       error_init (error);
+       return mono_icall_get_machine_name (error);
 }
 
 #ifndef HOST_WIN32
@@ -6485,17 +6488,18 @@ ves_icall_System_Environment_get_Platform (void)
 }
 
 #ifndef HOST_WIN32
-static inline MonoString *
-mono_icall_get_new_line (void)
+static inline MonoStringHandle
+mono_icall_get_new_line (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), "\n");
+       error_init (error);
+       return mono_string_new_handle (mono_domain_get (), "\n", error);
 }
 #endif /* !HOST_WIN32 */
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_get_NewLine (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_get_NewLine (MonoError *error)
 {
-       return mono_icall_get_new_line ();
+       return mono_icall_get_new_line (error);
 }
 
 #ifndef HOST_WIN32
@@ -6576,29 +6580,32 @@ ves_icall_System_Environment_GetCommandLineArgs (void)
 
 #ifndef HOST_WIN32
 static MonoArray *
-mono_icall_get_environment_variable_names (void)
+mono_icall_get_environment_variable_names (MonoError *error)
 {
-       MonoError error;
        MonoArray *names;
        MonoDomain *domain;
        MonoString *str;
        gchar **e, **parts;
        int n;
 
+       error_init (error);
        n = 0;
        for (e = environ; *e != 0; ++ e)
                ++ n;
 
        domain = mono_domain_get ();
-       names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       names = mono_array_new_checked (domain, mono_defaults.string_class, n, error);
+       return_val_if_nok (error, NULL);
 
        n = 0;
        for (e = environ; *e != 0; ++ e) {
                parts = g_strsplit (*e, "=", 2);
                if (*parts != 0) {
-                       str = mono_string_new (domain, *parts);
+                       str = mono_string_new_checked (domain, *parts, error);
+                       if (!is_ok (error)) {
+                               g_strfreev (parts);
+                               return NULL;
+                       }
                        mono_array_setref (names, n, str);
                }
 
@@ -6614,7 +6621,10 @@ mono_icall_get_environment_variable_names (void)
 ICALL_EXPORT MonoArray *
 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
 {
-       return mono_icall_get_environment_variable_names ();
+       MonoError error;
+       MonoArray *result = mono_icall_get_environment_variable_names (&error);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
 #ifndef HOST_WIN32
@@ -6683,18 +6693,19 @@ ves_icall_System_Environment_GetGacPath (MonoError *error)
 }
 
 #ifndef HOST_WIN32
-static inline MonoString *
-mono_icall_get_windows_folder_path (int folder)
+static inline MonoStringHandle
+mono_icall_get_windows_folder_path (int folder, MonoError *error)
 {
+       error_init (error);
        g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
-       return mono_string_new (mono_domain_get (), "");
+       return mono_string_new_handle (mono_domain_get (), "", error);
 }
 #endif /* !HOST_WIN32 */
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Environment_GetWindowsFolderPath (int folder)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetWindowsFolderPath (int folder, MonoError *error)
 {
-       return mono_icall_get_windows_folder_path (folder);
+       return mono_icall_get_windows_folder_path (folder, error);
 }
 
 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
index 8405b258498f7ffd5394a80109049d25fdb6e861..44e4b4ea4c1617bfb6763b10c06d931a30e5bbce 100644 (file)
@@ -22,7 +22,7 @@
 G_BEGIN_DECLS
 
 /* System.Environment */
-extern MonoString* ves_icall_System_Environment_get_UserName (void);
+extern MonoStringHandle ves_icall_System_Environment_get_UserName (MonoError *error);
 
 
 /* System.Security.Principal.WindowsIdentity */