Merge pull request #3056 from BrzVlad/fix-multiple-binprot
[mono.git] / mono / metadata / file-mmap-posix.c
index aca3e7fb49c6fab2a7f25c8b89aeca79d801763e..201c724a8f5d32a8a2c63c85b702f92d03762cd7 100644 (file)
@@ -5,6 +5,7 @@
  *     Rodrigo Kumpera
  *
  * Copyright 2014 Xamarin Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -226,13 +227,19 @@ is_special_zero_size_file (struct stat *buf)
 XXX implement options
 */
 static void*
-open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int access, int options, int *error)
+open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int access, int options, int *ioerror)
 {
+       MonoError error;
        struct stat buf;
-       char *c_path = path ? mono_string_to_utf8 (path) : NULL;
+       char *c_path = NULL;
        MmapHandle *handle = NULL;
        int result, fd;
 
+       if (path) {
+               c_path = mono_string_to_utf8_checked (path, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+       }
+
        if (path)
                result = stat (c_path, &buf);
        else
@@ -240,13 +247,13 @@ open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int a
 
        if (mode == FILE_MODE_TRUNCATE || mode == FILE_MODE_APPEND || mode == FILE_MODE_OPEN) {
                if (result == -1) { //XXX translate errno?
-                       *error = FILE_NOT_FOUND;
+                       *ioerror = FILE_NOT_FOUND;
                        goto done;
                }
        }
 
        if (mode == FILE_MODE_CREATE_NEW && result == 0) {
-               *error = FILE_ALREADY_EXISTS;
+               *ioerror = FILE_ALREADY_EXISTS;
                goto done;
        }
 
@@ -257,17 +264,17 @@ open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int a
                         * also makes little sense, so don't do the check if th file is one of these.
                         */
                        if (buf.st_size == 0 && !is_special_zero_size_file (&buf)) {
-                               *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+                               *ioerror = CAPACITY_SMALLER_THAN_FILE_SIZE;
                                goto done;
                        }
                        *capacity = buf.st_size;
                } else if (*capacity < buf.st_size) {
-                       *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+                       *ioerror = CAPACITY_SMALLER_THAN_FILE_SIZE;
                        goto done;
                }
        } else {
                if (mode == FILE_MODE_CREATE_NEW && *capacity == 0) {
-                       *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+                       *ioerror = CAPACITY_SMALLER_THAN_FILE_SIZE;
                        goto done;
                }
        }
@@ -278,7 +285,7 @@ open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int a
                fd = dup (input_fd);
 
        if (fd == -1) { //XXX translate errno?
-               *error = COULD_NOT_OPEN;
+               *ioerror = COULD_NOT_OPEN;
                goto done;
        }
 
@@ -298,27 +305,29 @@ done:
 
 #define MONO_ANON_FILE_TEMPLATE "/mono.anonmap.XXXXXXXXX"
 static void*
-open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *error)
+open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *ioerror)
 {
+       MonoError error;
        char *c_mapName;
        MmapHandle *handle;
        if (*capacity <= 1) {
-               *error = CAPACITY_MUST_BE_POSITIVE;
+               *ioerror = CAPACITY_MUST_BE_POSITIVE;
                return NULL;
        }
 
        if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) {
-               *error = INVALID_FILE_MODE;
+               *ioerror = INVALID_FILE_MODE;
                return NULL;
        }
 
-       c_mapName = mono_string_to_utf8 (mapName);
+       c_mapName = mono_string_to_utf8_checked (mapName, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        named_regions_lock ();
        handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
        if (handle) {
                if (mode == FILE_MODE_CREATE_NEW) {
-                       *error = FILE_ALREADY_EXISTS;
+                       *ioerror = FILE_ALREADY_EXISTS;
                        goto done;
                }
 
@@ -331,7 +340,7 @@ open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, in
                int unused G_GNUC_UNUSED, alloc_size;
 
                if (mode == FILE_MODE_OPEN) {
-                       *error = FILE_NOT_FOUND;
+                       *ioerror = FILE_NOT_FOUND;
                        goto done;
                }
                *capacity = align_up_to_page_size (*capacity);
@@ -339,7 +348,7 @@ open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, in
                tmp_dir = g_get_tmp_dir ();
                alloc_size = strlen (tmp_dir) + strlen (MONO_ANON_FILE_TEMPLATE) + 1;
                if (alloc_size > 1024) {//rather fail that stack overflow
-                       *error = COULD_NOT_MAP_MEMORY;
+                       *ioerror = COULD_NOT_MAP_MEMORY;
                        goto done;
                }
                file_name = (char *)alloca (alloc_size);
@@ -348,7 +357,7 @@ open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, in
 
                fd = mkstemp (file_name);
                if (fd == -1) {
-                       *error = COULD_NOT_MAP_MEMORY;
+                       *ioerror = COULD_NOT_MAP_MEMORY;
                        goto done;
                }
 
@@ -374,24 +383,26 @@ done:
 
 
 void *
-mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *ioerror)
 {
+       MonoError error;
        g_assert (path || mapName);
 
        if (!mapName)
-               return open_file_map (path, -1, mode, capacity, access, options, error);
+               return open_file_map (path, -1, mode, capacity, access, options, ioerror);
 
        if (path) {
                MmapHandle *handle;
-               char *c_mapName = mono_string_to_utf8 (mapName);
+               char *c_mapName = mono_string_to_utf8_checked (mapName, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
 
                named_regions_lock ();
                handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
                if (handle) {
-                       *error = FILE_ALREADY_EXISTS;
+                       *ioerror = FILE_ALREADY_EXISTS;
                        handle = NULL;
                } else {
-                       handle = (MmapHandle *)open_file_map (path, -1, mode, capacity, access, options, error);
+                       handle = (MmapHandle *)open_file_map (path, -1, mode, capacity, access, options, ioerror);
                        if (handle) {
                                handle->name = g_strdup (c_mapName);
                                g_hash_table_insert (named_regions, handle->name, handle);
@@ -403,26 +414,28 @@ mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *ca
                return handle;
        }
 
-       return open_memory_map (mapName, mode, capacity, access, options, error);
+       return open_memory_map (mapName, mode, capacity, access, options, ioerror);
 }
 
 void *
-mono_mmap_open_handle (void *input_fd, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+mono_mmap_open_handle (void *input_fd, MonoString *mapName, gint64 *capacity, int access, int options, int *ioerror)
 {
+       MonoError error;
        MmapHandle *handle;
        if (!mapName) {
-               handle = (MmapHandle *)open_file_map (NULL, GPOINTER_TO_INT (input_fd), FILE_MODE_OPEN, capacity, access, options, error);
+               handle = (MmapHandle *)open_file_map (NULL, GPOINTER_TO_INT (input_fd), FILE_MODE_OPEN, capacity, access, options, ioerror);
        } else {
-               char *c_mapName = mono_string_to_utf8 (mapName);
+               char *c_mapName = mono_string_to_utf8_checked (mapName, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
 
                named_regions_lock ();
                handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
                if (handle) {
-                       *error = FILE_ALREADY_EXISTS;
+                       *ioerror = FILE_ALREADY_EXISTS;
                        handle = NULL;
                } else {
                        //XXX we're exploiting wapi HANDLE == FD equivalence. THIS IS FRAGILE, create a _wapi_handle_to_fd call
-                       handle = (MmapHandle *)open_file_map (NULL, GPOINTER_TO_INT (input_fd), FILE_MODE_OPEN, capacity, access, options, error);
+                       handle = (MmapHandle *)open_file_map (NULL, GPOINTER_TO_INT (input_fd), FILE_MODE_OPEN, capacity, access, options, ioerror);
                        handle->name = g_strdup (c_mapName);
                        g_hash_table_insert (named_regions, handle->name, handle);
                }