-/*
- * w32file.c: File IO internal calls
+/**
+ * \file
+ * File IO internal calls
*
* Author:
* Dick Porter (dick@ximian.com)
ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
-static gchar *
-get_search_dir (const gunichar2 *pattern)
-{
- gchar *p;
- gchar *result;
-
- p = g_utf16_to_utf8 (pattern, -1, NULL, NULL, NULL);
- result = g_path_get_dirname (p);
- g_free (p);
- return result;
-}
-
-static GPtrArray *
-get_filesystem_entries (const gunichar2 *path,
- const gunichar2 *path_with_pattern,
- gint attrs, gint mask,
- gint32 *error)
-{
- int i;
- WIN32_FIND_DATA data;
- HANDLE find_handle;
- GPtrArray *names = NULL;
- gchar *utf8_path = NULL, *utf8_result, *full_name;
- gint32 attributes;
-
- mask = convert_attrs ((MonoFileAttributes)mask);
- attributes = get_file_attributes (path);
- if (attributes != -1) {
- if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- *error = ERROR_INVALID_NAME;
- goto fail;
- }
- } else {
- *error = mono_w32error_get_last ();
- goto fail;
- }
-
- find_handle = mono_w32file_find_first (path_with_pattern, &data);
- if (find_handle == INVALID_HANDLE_VALUE) {
- gint32 find_error = mono_w32error_get_last ();
-
- if (find_error == ERROR_FILE_NOT_FOUND || find_error == ERROR_NO_MORE_FILES) {
- /* No files, so just return an empty array */
- goto fail;
- }
-
- *error = find_error;
- goto fail;
- }
-
- utf8_path = get_search_dir (path_with_pattern);
- names = g_ptr_array_new ();
-
- do {
- if ((data.cFileName[0] == '.' && data.cFileName[1] == 0) ||
- (data.cFileName[0] == '.' && data.cFileName[1] == '.' && data.cFileName[2] == 0)) {
- continue;
- }
-
- if ((data.dwFileAttributes & mask) == attrs) {
- utf8_result = g_utf16_to_utf8 (data.cFileName, -1, NULL, NULL, NULL);
- if (utf8_result == NULL) {
- continue;
- }
-
- full_name = g_build_filename (utf8_path, utf8_result, NULL);
- g_ptr_array_add (names, full_name);
-
- g_free (utf8_result);
- }
- } while(mono_w32file_find_next (find_handle, &data));
-
- if (mono_w32file_find_close (find_handle) == FALSE) {
- *error = mono_w32error_get_last ();
- 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 *ioerror)
-{
- MonoError error;
- MonoDomain *domain = mono_domain_get ();
- MonoArray *result;
- int i;
- GPtrArray *names;
-
- *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.
- if (*ioerror == ERROR_SUCCESS) {
- MonoArray *arr = mono_array_new_checked (domain, mono_defaults.string_class, 0, &error);
- mono_error_set_pending_exception (&error);
- return arr;
- }
- return NULL;
- }
-
- result = mono_array_new_checked (domain, mono_defaults.string_class, names->len, &error);
- 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)));
- g_free (g_ptr_array_index (names, i));
- }
-leave:
- g_ptr_array_free (names, TRUE);
- return result;
-}
-
-typedef struct {
- MonoDomain *domain;
- gchar *utf8_path;
- HANDLE find_handle;
-} IncrementalFind;
-
-static gboolean
-incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, MonoString **result)
-{
- gchar *utf8_result;
- gchar *full_name;
-
- if ((data->cFileName[0] == '.' && data->cFileName[1] == 0) || (data->cFileName[0] == '.' && data->cFileName[1] == '.' && data->cFileName[2] == 0))
- return FALSE;
-
- utf8_result = g_utf16_to_utf8 (data->cFileName, -1, NULL, NULL, NULL);
- if (utf8_result == NULL)
- return FALSE;
-
- full_name = g_build_filename (handle->utf8_path, utf8_result, NULL);
- g_free (utf8_result);
- *result = mono_string_new (mono_domain_get (), full_name);
- g_free (full_name);
-
- return TRUE;
-}
-
HANDLE
ves_icall_System_IO_MonoIO_FindFirstFile (MonoString *path_with_pattern, MonoString **file_name, gint32 *file_attr, gint32 *ioerror)
{
return mono_w32file_find_close (hnd);
}
-/* FIXME make gc suspendable */
-MonoString *
-ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
- MonoString *path_with_pattern,
- gint32 *result_attr, gint32 *ioerror,
- gpointer *handle)
-{
- MonoError error;
- WIN32_FIND_DATA data;
- HANDLE find_handle;
- IncrementalFind *ifh;
- MonoString *result;
-
- *ioerror = ERROR_SUCCESS;
-
- find_handle = mono_w32file_find_first (mono_string_chars (path_with_pattern), &data);
-
- if (find_handle == INVALID_HANDLE_VALUE) {
- gint32 find_error = mono_w32error_get_last ();
- *handle = NULL;
-
- if (find_error == ERROR_FILE_NOT_FOUND)
- return NULL;
-
- *ioerror = find_error;
- return NULL;
- }
-
- ifh = g_new (IncrementalFind, 1);
- 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){
- if (mono_w32file_find_next (find_handle, &data) == FALSE){
- int e = mono_w32error_get_last ();
- if (e != ERROR_NO_MORE_FILES)
- *ioerror = e;
- return NULL;
- }
- }
- *result_attr = data.dwFileAttributes;
-
- return result;
-}
-
-/* FIXME make gc suspendable */
-MonoString *
-ves_icall_System_IO_MonoIO_FindNext (gpointer handle, gint32 *result_attr, gint32 *error)
-{
- IncrementalFind *ifh = (IncrementalFind *)handle;
- WIN32_FIND_DATA data;
- MonoString *result;
-
- *error = ERROR_SUCCESS;
- do {
- if (mono_w32file_find_next (ifh->find_handle, &data) == FALSE){
- int e = mono_w32error_get_last ();
- if (e != ERROR_NO_MORE_FILES)
- *error = e;
- return NULL;
- }
- } while (incremental_find_check_match (ifh, &data, &result) == 0);
-
- *result_attr = data.dwFileAttributes;
- return result;
-}
-
-int
-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;
-}
-
MonoString *
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;
ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
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));
/* if(ret==INVALID_FILE_ATTRIBUTES) { */
*error=mono_w32error_get_last ();
}
-
- MONO_EXIT_GC_SAFE;
return(ret);
}
gint32 *error)
{
gboolean ret;
- MONO_ENTER_GC_SAFE;
-
*error=ERROR_SUCCESS;
ret=mono_w32file_set_attributes (mono_string_chars (path),
if(ret==FALSE) {
*error=mono_w32error_get_last ();
}
-
- MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat, gint32 *error)
{
gboolean result;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
memset (stat, 0, sizeof (MonoIOStat));
}
- MONO_EXIT_GC_SAFE;
return result;
}
HANDLE ret;
int attributes, attrs;
gunichar2 *chars;
- MONO_ENTER_GC_SAFE;
chars = mono_string_chars (filename);
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
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);
}
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 ();
}
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 ();
gint32 *error)
{
gint32 offset_hi;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return offset | ((gint64)offset_hi << 32);
}
ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
const FILETIME *creation_filetime;
const FILETIME *access_filetime;
const FILETIME *write_filetime;
- MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
return(ret);
}
{
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 ();
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);
}
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;
}