[w32handle] Remove use of w32handle for File, Console, Pipe and Socket (#5319)
[mono.git] / mono / metadata / w32file.c
index d24506afd4ee1a71b1a8096c1f6f790e466d9412..325767f52434e9fbcb91aa60963c18d518354651 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * w32file.c: File IO internal calls
+/**
+ * \file
+ * File IO internal calls
  *
  * Author:
  *     Dick Porter (dick@ximian.com)
@@ -258,7 +259,6 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -267,7 +267,6 @@ ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
                *error=mono_w32error_get_last ();
        }
 
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -275,7 +274,6 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -284,7 +282,6 @@ ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
                *error=mono_w32error_get_last ();
        }
 
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -392,9 +389,7 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
        
        *ioerror = ERROR_SUCCESS;
 
-       MONO_ENTER_GC_SAFE;
        names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, ioerror);
-       MONO_EXIT_GC_SAFE;
 
        if (!names) {
                // If there's no array and no error, then return an empty array.
@@ -410,7 +405,10 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path,
        if (mono_error_set_pending_exception (&error))
                goto leave;
        for (i = 0; i < names->len; i++) {
-               mono_array_setref (result, i, mono_string_new (domain, (const char *)g_ptr_array_index (names, i)));
+               MonoString *name = mono_string_new_checked (domain, (const char *)g_ptr_array_index (names, i), &error);
+               if (mono_error_set_pending_exception (&error))
+                       goto leave;
+               mono_array_setref (result, i, name);
                g_free (g_ptr_array_index (names, i));
        }
 leave:
@@ -425,8 +423,9 @@ typedef struct {
 } IncrementalFind;
        
 static gboolean
-incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, MonoString **result)
+incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, MonoString **result, MonoError *error)
 {
+       error_init (error);
        gchar *utf8_result;
        gchar *full_name;
        
@@ -439,8 +438,10 @@ incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, Mo
        
        full_name = g_build_filename (handle->utf8_path, utf8_result, NULL);
        g_free (utf8_result);
-       *result = mono_string_new (mono_domain_get (), full_name);
+       *result = mono_string_new_checked (mono_domain_get (), full_name, error);
        g_free (full_name);
+       if (!is_ok (error))
+               return FALSE;
        
        return TRUE;
 }
@@ -533,16 +534,18 @@ ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
        ifh->find_handle = find_handle;
        ifh->utf8_path = mono_string_to_utf8_checked (path, &error);
        if (mono_error_set_pending_exception (&error)) {
-               MONO_ENTER_GC_SAFE;
                mono_w32file_find_close (find_handle);
-               MONO_EXIT_GC_SAFE;
                g_free (ifh);
                return NULL;
        }
        ifh->domain = mono_domain_get ();
        *handle = ifh;
 
-       while (incremental_find_check_match (ifh, &data, &result) == 0){
+       while (incremental_find_check_match (ifh, &data, &result, &error) == 0){
+               if (!is_ok (&error)) {
+                       mono_error_set_pending_exception (&error);
+                       return NULL;
+               }
                if (mono_w32file_find_next (find_handle, &data) == FALSE){
                        int e = mono_w32error_get_last ();
                        if (e != ERROR_NO_MORE_FILES)
@@ -551,27 +554,33 @@ ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
                }
        }
        *result_attr = data.dwFileAttributes;
-       
+
        return result;
 }
 
 /* FIXME make gc suspendable */
 MonoString *
-ves_icall_System_IO_MonoIO_FindNext (gpointer handle, gint32 *result_attr, gint32 *error)
+ves_icall_System_IO_MonoIO_FindNext (gpointer handle, gint32 *result_attr, gint32 *ioerror)
 {
+       MonoError error;
        IncrementalFind *ifh = (IncrementalFind *)handle;
        WIN32_FIND_DATA data;
        MonoString *result;
 
-       *error = ERROR_SUCCESS;
+       error_init (&error);
+       *ioerror = ERROR_SUCCESS;
        do {
+               if (!is_ok (&error)) {
+                       mono_error_set_pending_exception (&error);
+                       return NULL;
+               }
                if (mono_w32file_find_next (ifh->find_handle, &data) == FALSE){
                        int e = mono_w32error_get_last ();
                        if (e != ERROR_NO_MORE_FILES)
-                               *error = e;
+                               *ioerror = e;
                        return NULL;
                }
-       } while (incremental_find_check_match (ifh, &data, &result) == 0);
+       } while (incremental_find_check_match (ifh, &data, &result, &error) == 0);
 
        *result_attr = data.dwFileAttributes;
        return result;
@@ -583,14 +592,12 @@ ves_icall_System_IO_MonoIO_FindClose (gpointer handle)
        IncrementalFind *ifh = (IncrementalFind *)handle;
        gint32 error;
 
-       MONO_ENTER_GC_SAFE;
        if (mono_w32file_find_close (ifh->find_handle) == FALSE){
                error = mono_w32error_get_last ();
        } else
                error = ERROR_SUCCESS;
        g_free (ifh->utf8_path);
        g_free (ifh);
-       MONO_EXIT_GC_SAFE;
 
        return error;
 }
@@ -606,7 +613,7 @@ ves_icall_System_IO_MonoIO_GetCurrentDirectory (gint32 *io_error)
        len = MAX_PATH + 1; /*FIXME this is too smal under most unix systems.*/
        buf = g_new (gunichar2, len);
        
-       mono_error_init (&error);
+       error_init (&error);
        *io_error=ERROR_SUCCESS;
        result = NULL;
 
@@ -692,7 +699,6 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
        
        *error=ERROR_SUCCESS;
        
@@ -701,7 +707,6 @@ ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
                *error=mono_w32error_get_last ();
        }
        
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -709,8 +714,6 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
 {
        gint32 ret;
-       MONO_ENTER_GC_SAFE;
-
        *error=ERROR_SUCCESS;
        
        ret=get_file_attributes (mono_string_chars (path));
@@ -725,8 +728,6 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
          /* if(ret==INVALID_FILE_ATTRIBUTES) { */
                *error=mono_w32error_get_last ();
        }
-       
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -735,8 +736,6 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
                                              gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
-       
        *error=ERROR_SUCCESS;
        
        ret=mono_w32file_set_attributes (mono_string_chars (path),
@@ -744,8 +743,6 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs,
        if(ret==FALSE) {
                *error=mono_w32error_get_last ();
        }
-
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -753,7 +750,6 @@ gint32
 ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -765,7 +761,6 @@ ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
                *error=mono_w32error_get_last ();
        }
        
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -773,7 +768,6 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat, gint32 *error)
 {
        gboolean result;
-       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -784,7 +778,6 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat, gint
                memset (stat, 0, sizeof (MonoIOStat));
        }
 
-       MONO_EXIT_GC_SAFE;
        return result;
 }
 
@@ -796,7 +789,6 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
        HANDLE ret;
        int attributes, attrs;
        gunichar2 *chars;
-       MONO_ENTER_GC_SAFE;
 
        chars = mono_string_chars (filename);   
        *error=ERROR_SUCCESS;
@@ -835,7 +827,6 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
                *error=mono_w32error_get_last ();
        } 
        
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -843,16 +834,12 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
-
        *error=ERROR_SUCCESS;
        
        ret=mono_w32file_close (handle);
        if(ret==FALSE) {
                *error=mono_w32error_get_last ();
        }
-       
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -876,9 +863,7 @@ ves_icall_System_IO_MonoIO_Read (HANDLE handle, MonoArray *dest,
 
        buffer = mono_array_addr (dest, guchar, dest_offset);
 
-       MONO_ENTER_GC_SAFE;
        result = mono_w32file_read (handle, buffer, count, &n);
-       MONO_EXIT_GC_SAFE;
 
        if (!result) {
                *error=mono_w32error_get_last ();
@@ -907,9 +892,7 @@ ves_icall_System_IO_MonoIO_Write (HANDLE handle, MonoArray *src,
        }
        
        buffer = mono_array_addr (src, guchar, src_offset);
-       MONO_ENTER_GC_SAFE;
        result = mono_w32file_write (handle, buffer, count, &n);
-       MONO_EXIT_GC_SAFE;
 
        if (!result) {
                *error=mono_w32error_get_last ();
@@ -924,7 +907,6 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                                 gint32 *error)
 {
        gint32 offset_hi;
-       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -936,7 +918,6 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin,
                *error=mono_w32error_get_last ();
        }
 
-       MONO_EXIT_GC_SAFE;
        return offset | ((gint64)offset_hi << 32);
 }
 
@@ -944,7 +925,6 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
 {
        gboolean ret;
-       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -953,7 +933,6 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
                *error=mono_w32error_get_last ();
        }
        
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -1022,7 +1001,6 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
        const FILETIME *creation_filetime;
        const FILETIME *access_filetime;
        const FILETIME *write_filetime;
-       MONO_ENTER_GC_SAFE;
 
        *error=ERROR_SUCCESS;
        
@@ -1046,7 +1024,6 @@ ves_icall_System_IO_MonoIO_SetFileTime (HANDLE handle, gint64 creation_time,
                *error=mono_w32error_get_last ();
        }
 
-       MONO_EXIT_GC_SAFE;
        return(ret);
 }
 
@@ -1073,9 +1050,7 @@ ves_icall_System_IO_MonoIO_CreatePipe (HANDLE *read_handle, HANDLE *write_handle
 {
        gboolean ret;
 
-       MONO_ENTER_GC_SAFE;
        ret=mono_w32file_create_pipe (read_handle, write_handle, 0);
-       MONO_EXIT_GC_SAFE;
 
        if(ret==FALSE) {
                *error = mono_w32error_get_last ();
@@ -1090,25 +1065,22 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, HANDLE source_handle,
                HANDLE target_process_handle, HANDLE *target_handle, gint32 access, gint32 inherit, gint32 options, gint32 *error)
 {
-       /* This is only used on Windows */
+#ifndef HOST_WIN32
+       *target_handle = mono_w32handle_duplicate (source_handle);
+#else
        gboolean ret;
-       
+
        MONO_ENTER_GC_SAFE;
-#ifdef HOST_WIN32
        ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
-#else
-       mono_w32handle_ref (source_handle);
-       *target_handle = source_handle;
-       ret = TRUE;
-#endif
        MONO_EXIT_GC_SAFE;
 
-       if(ret==FALSE) {
+       if (!ret) {
                *error = mono_w32error_get_last ();
                /* FIXME: throw an exception? */
                return(FALSE);
        }
-       
+#endif
+
        return(TRUE);
 }
 
@@ -1209,15 +1181,17 @@ mono_filesize_from_path (MonoString *string)
        char *path = mono_string_to_utf8_checked (string, &error);
        mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
 
+       gint stat_res;
        MONO_ENTER_GC_SAFE;
-       if (stat (path, &buf) == -1)
+       stat_res = stat (path, &buf);
+       MONO_EXIT_GC_SAFE;
+       if (stat_res == -1)
                res = -1;
        else
                res = (gint64)buf.st_size;
 
        g_free (path);
 
-       MONO_EXIT_GC_SAFE;
        return res;
 }