X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ffile-io.c;h=c4bb6df67659c364a42f5a2a2c47943bea43b63c;hb=24748ce981a554c4a8f9529e5848a88c743a1901;hp=097da28a8c73806199a74aaed65c4010fa6dfcd4;hpb=f777bc37a485df19a4700d5c41e9e58bdfa2ef54;p=mono.git diff --git a/mono/metadata/file-io.c b/mono/metadata/file-io.c index 097da28a8c7..c4bb6df6765 100644 --- a/mono/metadata/file-io.c +++ b/mono/metadata/file-io.c @@ -269,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); } @@ -286,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); } @@ -311,37 +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; - result = NULL; - *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; - goto leave; + goto fail; } } else { *error = GetLastError (); - goto leave; + goto fail; } find_handle = FindFirstFile (mono_string_chars (path_with_pattern), &data); @@ -350,11 +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 */ - goto leave; + goto fail; } *error = find_error; - goto leave; + goto fail; } utf8_path = get_search_dir (path_with_pattern); @@ -381,25 +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; } - for (i = 0; i < names->len; i++) { - g_free (g_ptr_array_index (names, i)); + 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_ptr_array_free (names, TRUE); g_free (utf8_path); + return FALSE; +} -leave: - // If there's no array and no error, then return an empty array. - if (result == NULL && *error == ERROR_SUCCESS) - result = mono_array_new (domain, mono_defaults.string_class, 0); +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); return result; } @@ -430,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, @@ -475,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) { @@ -501,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; } @@ -519,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); @@ -555,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)); @@ -572,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); } @@ -593,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); @@ -613,6 +631,7 @@ ves_icall_System_IO_MonoIO_ReplaceFile (MonoString *sourceFileName, MonoString * if (ret == FALSE) *error = GetLastError (); + MONO_FINISH_BLOCKING return ret; } @@ -621,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); @@ -631,6 +649,7 @@ ves_icall_System_IO_MonoIO_CopyFile (MonoString *path, MonoString *dest, *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -638,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)); @@ -648,6 +666,7 @@ ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error) *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -655,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; @@ -673,6 +691,7 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error) *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -681,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), @@ -691,7 +709,8 @@ ves_icall_System_IO_MonoIO_SetFileAttributes (MonoString *path, gint32 attrs, if(ret==FALSE) { *error=GetLastError (); } - + + MONO_FINISH_BLOCKING return(ret); } @@ -699,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; @@ -712,6 +730,7 @@ ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error) *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -721,8 +740,7 @@ 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; @@ -735,6 +753,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat, memset (stat, 0, sizeof (MonoIOStat)); } + MONO_FINISH_BLOCKING return result; } @@ -745,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){ @@ -791,6 +810,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode, *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -798,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; @@ -808,6 +827,7 @@ ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error) *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -820,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); + MONO_CHECK_ARG_NULL (dest, 0); - if (dest_offset > mono_array_length (dest) - count) - mono_raise_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong.")); + 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 (); @@ -849,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 > mono_array_length (src) - count) - mono_raise_exception (mono_get_exception_argument ("array", "array too small. numBytes/offset wrong.")); + 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 (); @@ -874,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; @@ -886,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); } @@ -894,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; @@ -904,6 +928,7 @@ ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error) *error=GetLastError (); } + MONO_FINISH_BLOCKING return(ret); } @@ -912,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; @@ -922,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) @@ -934,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 */ @@ -984,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; @@ -1008,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); } @@ -1043,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); @@ -1065,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); @@ -1147,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); @@ -1165,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); @@ -1174,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 @@ -1193,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; @@ -1201,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; @@ -1215,6 +1239,8 @@ 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. @@ -1227,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; } @@ -1241,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;