Merge pull request #1952 from esdrubal/proc_name
[mono.git] / mono / metadata / file-io.c
index 6f1f3c3da50bc1f729a14f94d8b429ebb790f11f..6f326513995b002d1d30263e77c9a0696ecd071d 100644 (file)
@@ -7,6 +7,7 @@
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2012 Xamarin Inc (http://www.xamarin.com)
  */
 
 #include <config.h>
@@ -174,21 +175,13 @@ static gint64 convert_filetime (const FILETIME *filetime)
        return (gint64)ticks;
 }
 
-static void convert_win32_file_attribute_data (const WIN32_FILE_ATTRIBUTE_DATA *data, const gunichar2 *name, MonoIOStat *stat)
+static void convert_win32_file_attribute_data (const WIN32_FILE_ATTRIBUTE_DATA *data, MonoIOStat *stat)
 {
-       int len;
-       
        stat->attributes = data->dwFileAttributes;
        stat->creation_time = convert_filetime (&data->ftCreationTime);
        stat->last_access_time = convert_filetime (&data->ftLastAccessTime);
        stat->last_write_time = convert_filetime (&data->ftLastWriteTime);
        stat->length = ((gint64)data->nFileSizeHigh << 32) | data->nFileSizeLow;
-
-       len = 0;
-       while (name [len])
-               ++ len;
-
-       MONO_STRUCT_SETREF (stat, name, mono_string_new_utf16 (mono_domain_get (), name, len));
 }
 
 /* Managed file attributes have nearly but not quite the same values
@@ -276,16 +269,16 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        ret=CreateDirectory (mono_string_chars (path), NULL);
        if(ret==FALSE) {
                *error=GetLastError ();
        }
-       
+
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -293,16 +286,16 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        ret=RemoveDirectory (mono_string_chars (path));
        if(ret==FALSE) {
                *error=GetLastError ();
        }
-       
+
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -318,36 +311,29 @@ get_search_dir (MonoString *pattern)
        return result;
 }
 
-MonoArray *
-ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
+static GPtrArray *
+get_filesystem_entries (MonoString *path,
                                                 MonoString *path_with_pattern,
                                                 gint attrs, gint mask,
                                                 gint32 *error)
 {
-       MonoDomain *domain;
-       MonoArray *result;
        int i;
        WIN32_FIND_DATA data;
        HANDLE find_handle;
-       GPtrArray *names;
-       gchar *utf8_path, *utf8_result, *full_name;
+       GPtrArray *names = NULL;
+       gchar *utf8_path = NULL, *utf8_result, *full_name;
        gint32 attributes;
-       
-       MONO_ARCH_SAVE_REGS;
-
-       *error = ERROR_SUCCESS;
 
-       domain = mono_domain_get ();
        mask = convert_attrs (mask);
        attributes = get_file_attributes (mono_string_chars (path));
        if (attributes != -1) {
                if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
                        *error = ERROR_INVALID_NAME;
-                       return (NULL);
+                       goto fail;
                }
        } else {
                *error = GetLastError ();
-               return (NULL);
+               goto fail;
        }
        
        find_handle = FindFirstFile (mono_string_chars (path_with_pattern), &data);
@@ -356,15 +342,11 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
                
                if (find_error == ERROR_FILE_NOT_FOUND || find_error == ERROR_NO_MORE_FILES) {
                        /* No files, so just return an empty array */
-                       result = mono_array_new (domain,
-                                                mono_defaults.string_class,
-                                                0);
-
-                       return(result);
+                       goto fail;
                }
                
                *error = find_error;
-               return(NULL);
+               goto fail;
        }
 
        utf8_path = get_search_dir (path_with_pattern);
@@ -391,20 +373,52 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
 
        if (FindClose (find_handle) == FALSE) {
                *error = GetLastError ();
-               result = NULL;
-       } else {
-               result = mono_array_new (domain, mono_defaults.string_class, names->len);
-               for (i = 0; i < names->len; i++) {
-                       mono_array_setref (result, i, mono_string_new (domain, g_ptr_array_index (names, i)));
-               }
+               goto fail;
        }
 
+       g_free (utf8_path);
+       return names;
+fail:
+       if (names) {
+               for (i = 0; i < names->len; i++)
+                       g_free (g_ptr_array_index (names, i));
+               g_ptr_array_free (names, TRUE);
+       }
+       g_free (utf8_path);
+       return FALSE;
+}
+
+
+MonoArray *
+ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
+                                                MonoString *path_with_pattern,
+                                                gint attrs, gint mask,
+                                                gint32 *error)
+{
+       MonoDomain *domain = mono_domain_get ();
+       MonoArray *result;
+       int i;
+       GPtrArray *names;
+       
+       *error = ERROR_SUCCESS;
+
+       MONO_PREPARE_BLOCKING;
+       names = get_filesystem_entries (path, path_with_pattern, attrs, mask, error);
+       MONO_FINISH_BLOCKING;
+
+       if (!names) {
+               // If there's no array and no error, then return an empty array.
+               if (*error == ERROR_SUCCESS)
+                       return mono_array_new (domain, mono_defaults.string_class, 0);
+               return NULL;
+       }
+
+       result = mono_array_new (domain, mono_defaults.string_class, names->len);
        for (i = 0; i < names->len; i++) {
+               mono_array_setref (result, i, mono_string_new (domain, g_ptr_array_index (names, i)));
                g_free (g_ptr_array_index (names, i));
        }
        g_ptr_array_free (names, TRUE);
-       g_free (utf8_path);
-       
        return result;
 }
 
@@ -435,6 +449,7 @@ incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, Mo
        return TRUE;
 }
 
+/* FIXME make gc suspendable */
 MonoString *
 ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
                                      MonoString *path_with_pattern,
@@ -480,6 +495,7 @@ ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
        return result;
 }
 
+/* FIXME make gc suspendable */
 MonoString *
 ves_icall_System_IO_MonoIO_FindNext (gpointer handle, gint32 *result_attr, gint32 *error)
 {
@@ -487,7 +503,7 @@ ves_icall_System_IO_MonoIO_FindNext (gpointer handle, gint32 *result_attr, gint3
        WIN32_FIND_DATA data;
        MonoString *result;
 
-       error = ERROR_SUCCESS;
+       *error = ERROR_SUCCESS;
        do {
                if (FindNextFile (ifh->find_handle, &data) == FALSE){
                        int e = GetLastError ();
@@ -506,13 +522,15 @@ ves_icall_System_IO_MonoIO_FindClose (gpointer handle)
 {
        IncrementalFind *ifh = handle;
        gint32 error;
-       
+
+       MONO_PREPARE_BLOCKING;
        if (FindClose (ifh->find_handle) == FALSE){
                error = GetLastError ();
        } else
                error = ERROR_SUCCESS;
        g_free (ifh->utf8_path);
        g_free (ifh);
+       MONO_FINISH_BLOCKING;
 
        return error;
 }
@@ -524,8 +542,6 @@ ves_icall_System_IO_MonoIO_GetCurrentDirectory (gint32 *error)
        gunichar2 *buf;
        int len, res_len;
 
-       MONO_ARCH_SAVE_REGS;
-
        len = MAX_PATH + 1; /*FIXME this is too smal under most unix systems.*/
        buf = g_new (gunichar2, len);
        
@@ -560,8 +576,6 @@ ves_icall_System_IO_MonoIO_SetCurrentDirectory (MonoString *path,
 {
        gboolean ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        ret=SetCurrentDirectory (mono_string_chars (path));
@@ -577,16 +591,16 @@ ves_icall_System_IO_MonoIO_MoveFile (MonoString *path, MonoString *dest,
                                     gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
-       
+
        ret=MoveFile (mono_string_chars (path), mono_string_chars (dest));
        if(ret==FALSE) {
                *error=GetLastError ();
        }
-       
+
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -598,8 +612,7 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
        gboolean ret;
        gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
        guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
-
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        if (sourceFileName)
                utf16_sourceFileName = mono_string_chars (sourceFileName);
@@ -612,11 +625,13 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString *
        if (ignoreMetadataErrors)
                replaceFlags |= REPLACEFILE_IGNORE_MERGE_ERRORS;
 
+       /* FIXME: source and destination file names must not be NULL, but apparently they might be! */
        ret = ReplaceFile (utf16_destinationFileName, utf16_sourceFileName, utf16_destinationBackupFileName,
                         replaceFlags, NULL, NULL);
        if (ret == FALSE)
                *error = GetLastError ();
 
+       MONO_FINISH_BLOCKING;
        return ret;
 }
 
@@ -625,9 +640,8 @@ ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
                                     MonoBoolean overwrite, gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        ret=CopyFile (mono_string_chars (path), mono_string_chars (dest), !overwrite);
@@ -635,6 +649,7 @@ ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest,
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -642,9 +657,8 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        ret=DeleteFile (mono_string_chars (path));
@@ -652,6 +666,7 @@ ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -659,8 +674,7 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
 {
        gint32 ret;
-       
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -677,6 +691,7 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -685,9 +700,8 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
                                              gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        ret=SetFileAttributes (mono_string_chars (path),
@@ -695,7 +709,8 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
        if(ret==FALSE) {
                *error=GetLastError ();
        }
-       
+
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -703,8 +718,7 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -716,6 +730,7 @@ ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -725,22 +740,20 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat,
 {
        gboolean result;
        WIN32_FILE_ATTRIBUTE_DATA data;
-
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
        result = get_file_attributes_ex (mono_string_chars (path), &data);
 
        if (result) {
-               convert_win32_file_attribute_data (&data,
-                                                  mono_string_chars (path),
-                                                  stat);
+               convert_win32_file_attribute_data (&data, stat);
        } else {
                *error=GetLastError ();
                memset (stat, 0, sizeof (MonoIOStat));
        }
 
+       MONO_FINISH_BLOCKING;
        return result;
 }
 
@@ -751,10 +764,10 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
 {
        HANDLE ret;
        int attributes, attrs;
-       gunichar2 *chars = mono_string_chars (filename);
-       
-       MONO_ARCH_SAVE_REGS;
+       gunichar2 *chars;
+       MONO_PREPARE_BLOCKING;
 
+       chars = mono_string_chars (filename);   
        *error=ERROR_SUCCESS;
 
        if (options != 0){
@@ -797,6 +810,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
                *error=GetLastError ();
        } 
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -804,8 +818,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -814,6 +827,7 @@ ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -826,17 +840,20 @@ ves_icall_System_IO_MonoIO_Read (HANDLE handle, MonoArray *dest,
        gboolean result;
        guint32 n;
 
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
 
-       MONO_CHECK_ARG_NULL (dest);
-       
-       if (dest_offset + count > mono_array_length (dest))
+       MONO_CHECK_ARG_NULL (dest, 0);
+
+       if (dest_offset > mono_array_length (dest) - count) {
+               mono_set_pending_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong."));
                return 0;
+       }
 
        buffer = mono_array_addr (dest, guchar, dest_offset);
+
+       MONO_PREPARE_BLOCKING;
        result = ReadFile (handle, buffer, count, &n, NULL);
+       MONO_FINISH_BLOCKING;
 
        if (!result) {
                *error=GetLastError ();
@@ -855,17 +872,19 @@ ves_icall_System_IO_MonoIO_Write (HANDLE handle, MonoArray *src,
        gboolean result;
        guint32 n;
 
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
 
-       MONO_CHECK_ARG_NULL (src);
+       MONO_CHECK_ARG_NULL (src, 0);
        
-       if (src_offset + count > mono_array_length (src))
+       if (src_offset > mono_array_length (src) - count) {
+               mono_set_pending_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong."));
                return 0;
+       }
        
        buffer = mono_array_addr (src, guchar, src_offset);
+       MONO_PREPARE_BLOCKING;
        result = WriteFile (handle, buffer, count, &n, NULL);
+       MONO_FINISH_BLOCKING;
 
        if (!result) {
                *error=GetLastError ();
@@ -880,8 +899,7 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                                 gint32 *error)
 {
        gint32 offset_hi;
-
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -892,7 +910,8 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
        if(offset==INVALID_SET_FILE_POINTER) {
                *error=GetLastError ();
        }
-       
+
+       MONO_FINISH_BLOCKING;
        return offset | ((gint64)offset_hi << 32);
 }
 
@@ -900,8 +919,7 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -910,6 +928,7 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
@@ -918,8 +937,7 @@ ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
 {
        gint64 length;
        guint32 length_hi;
-
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -928,9 +946,11 @@ ves_icall_System_IO_MonoIO_GetLength (HANDLE handle, gint32 *error)
                *error=GetLastError ();
        }
        
+       MONO_FINISH_BLOCKING;
        return length | ((gint64)length_hi << 32);
 }
 
+/* FIXME make gc suspendable */
 MonoBoolean
 ves_icall_System_IO_MonoIO_SetLength (HANDLE handle, gint64 length,
                                      gint32 *error)
@@ -940,8 +960,6 @@ ves_icall_System_IO_MonoIO_SetLength (HANDLE handle, gint64 length,
        gint32 length_hi;
        gboolean result;
 
-       MONO_ARCH_SAVE_REGS;
-
        *error=ERROR_SUCCESS;
        
        /* save file pointer */
@@ -990,8 +1008,7 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
        const FILETIME *creation_filetime;
        const FILETIME *last_access_filetime;
        const FILETIME *last_write_filetime;
-
-       MONO_ARCH_SAVE_REGS;
+       MONO_PREPARE_BLOCKING;
 
        *error=ERROR_SUCCESS;
        
@@ -1014,31 +1031,26 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
        if(ret==FALSE) {
                *error=GetLastError ();
        }
-       
+
+       MONO_FINISH_BLOCKING;
        return(ret);
 }
 
 HANDLE 
 ves_icall_System_IO_MonoIO_get_ConsoleOutput ()
 {
-       MONO_ARCH_SAVE_REGS;
-
        return GetStdHandle (STD_OUTPUT_HANDLE);
 }
 
 HANDLE 
 ves_icall_System_IO_MonoIO_get_ConsoleInput ()
 {
-       MONO_ARCH_SAVE_REGS;
-
        return GetStdHandle (STD_INPUT_HANDLE);
 }
 
 HANDLE 
 ves_icall_System_IO_MonoIO_get_ConsoleError ()
 {
-       MONO_ARCH_SAVE_REGS;
-
        return GetStdHandle (STD_ERROR_HANDLE);
 }
 
@@ -1049,13 +1061,14 @@ ves_icall_System_IO_MonoIO_CreatePipe (HANDLE *read_handle,
        SECURITY_ATTRIBUTES attr;
        gboolean ret;
        
-       MONO_ARCH_SAVE_REGS;
-
        attr.nLength=sizeof(SECURITY_ATTRIBUTES);
        attr.bInheritHandle=TRUE;
        attr.lpSecurityDescriptor=NULL;
-       
+
+       MONO_PREPARE_BLOCKING;
        ret=CreatePipe (read_handle, write_handle, &attr, 0);
+       MONO_FINISH_BLOCKING;
+
        if(ret==FALSE) {
                /* FIXME: throw an exception? */
                return(FALSE);
@@ -1071,9 +1084,10 @@ MonoBoolean ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_ha
        /* This is only used on Windows */
        gboolean ret;
        
-       MONO_ARCH_SAVE_REGS;
-       
+       MONO_PREPARE_BLOCKING;
        ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
+       MONO_FINISH_BLOCKING;
+
        if(ret==FALSE) {
                /* FIXME: throw an exception? */
                return(FALSE);
@@ -1153,8 +1167,6 @@ ves_icall_System_IO_MonoIO_get_InvalidPathChars ()
        MonoDomain *domain;
        int i, n;
 
-       MONO_ARCH_SAVE_REGS;
-
        domain = mono_domain_get ();
        n = sizeof (invalid_path_chars) / sizeof (gunichar2);
        chars = mono_array_new (domain, mono_defaults.char_class, n);
@@ -1171,6 +1183,7 @@ ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name)
        gunichar2 *name;
        int ret;
 
+       MONO_PREPARE_BLOCKING;
        name=g_new0 (gunichar2, 256);
        
        ret=GetTempPath (256, name);
@@ -1180,6 +1193,7 @@ ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name)
                name=g_new0 (gunichar2, ret+2); /* include the terminator */
                ret=GetTempPath (ret, name);
        }
+       MONO_FINISH_BLOCKING;
        
        if(ret>0) {
 #ifdef DEBUG
@@ -1199,6 +1213,7 @@ void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
                                      gint64 length, gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -1207,12 +1222,15 @@ void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
        if (ret == FALSE) {
                *error = GetLastError ();
        }
+
+       MONO_FINISH_BLOCKING;
 }
 
 void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
                                        gint64 length, gint32 *error)
 {
        gboolean ret;
+       MONO_PREPARE_BLOCKING;
        
        *error=ERROR_SUCCESS;
        
@@ -1221,11 +1239,13 @@ void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
        if (ret == FALSE) {
                *error = GetLastError ();
        }
+
+       MONO_FINISH_BLOCKING;
 }
 
 //Support for io-layer free mmap'd files.
 
-#if (defined (__MACH__) && defined (TARGET_ARM)) || defined (TARGET_ANDROID)
+#if defined (TARGET_IOS) || defined (TARGET_ANDROID)
 
 gint64
 mono_filesize_from_path (MonoString *string)
@@ -1233,13 +1253,16 @@ mono_filesize_from_path (MonoString *string)
        struct stat buf;
        gint64 res;
        char *path = mono_string_to_utf8 (string);
-       
+
+       MONO_PREPARE_BLOCKING;
        if (stat (path, &buf) == -1)
                res = -1;
        else
                res = (gint64)buf.st_size;
 
        g_free (path);
+
+       MONO_FINISH_BLOCKING;
        return res;
 }
 
@@ -1247,8 +1270,13 @@ gint64
 mono_filesize_from_fd (int fd)
 {
        struct stat buf;
+       int res;
 
-       if (fstat (fd, &buf) == -1)
+       MONO_PREPARE_BLOCKING;
+       res = fstat (fd, &buf);
+       MONO_FINISH_BLOCKING;
+       
+       if (res == -1)
                return (gint64)-1;
 
        return (gint64)buf.st_size;