X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ffile-mmap-posix.c;h=3c971a091b5f907ea864a239e9e118b5f121e162;hb=074c3c2693e34037af9c551f40613019f5d42996;hp=201c724a8f5d32a8a2c63c85b702f92d03762cd7;hpb=c6d3cc5fa7e759a8b36f1a4bd15a65312b7c7120;p=mono.git diff --git a/mono/metadata/file-mmap-posix.c b/mono/metadata/file-mmap-posix.c index 201c724a8f5..3c971a091b5 100644 --- a/mono/metadata/file-mmap-posix.c +++ b/mono/metadata/file-mmap-posix.c @@ -1,5 +1,6 @@ -/* - * file-mmap-posix.c: File mmap internal calls +/** + * \file + * File mmap internal calls * * Author: * Rodrigo Kumpera @@ -32,7 +33,7 @@ #include -#include +#include #include #include #include @@ -63,7 +64,9 @@ enum { COULD_NOT_OPEN, CAPACITY_MUST_BE_POSITIVE, INVALID_FILE_MODE, - COULD_NOT_MAP_MEMORY + COULD_NOT_MAP_MEMORY, + ACCESS_DENIED, + CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE }; enum { @@ -227,20 +230,13 @@ 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 *ioerror) +open_file_map (const char *c_path, int input_fd, int mode, gint64 *capacity, int access, int options, int *ioerror) { - MonoError error; struct stat buf; - 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) + if (c_path) result = stat (c_path, &buf); else result = fstat (input_fd, &buf); @@ -279,7 +275,7 @@ open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int a } } - if (path) //FIXME use io portability? + if (c_path) //FIXME use io portability? fd = open (c_path, file_mode_to_unix (mode) | access_mode_to_unix (access), DEFAULT_FILEMODE); else fd = dup (input_fd); @@ -299,30 +295,30 @@ open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int a handle->fd = fd; done: - g_free (c_path); return (void*)handle; } #define MONO_ANON_FILE_TEMPLATE "/mono.anonmap.XXXXXXXXX" static void* -open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *ioerror) +open_memory_map (const char *c_mapName, int mode, gint64 *capacity, int access, int options, int *ioerror) { - MonoError error; - char *c_mapName; MmapHandle *handle; - if (*capacity <= 1) { + if (*capacity <= 0 && mode != FILE_MODE_OPEN) { *ioerror = CAPACITY_MUST_BE_POSITIVE; return NULL; } +#if SIZEOF_VOID_P == 4 + if (*capacity > UINT32_MAX) { + *ioerror = CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE; + return NULL; + } +#endif if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) { *ioerror = INVALID_FILE_MODE; return NULL; } - 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) { @@ -377,46 +373,59 @@ open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, in done: named_regions_unlock (); - g_free (c_mapName); return handle; } +/* This is an icall */ void * mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *ioerror) { MonoError error; + MmapHandle *handle = NULL; g_assert (path || mapName); - if (!mapName) - return open_file_map (path, -1, mode, capacity, access, options, ioerror); + if (!mapName) { + char * c_path = mono_string_to_utf8_checked (path, &error); + if (mono_error_set_pending_exception (&error)) + return NULL; + handle = open_file_map (c_path, -1, mode, capacity, access, options, ioerror); + g_free (c_path); + return handle; + } + + char *c_mapName = mono_string_to_utf8_checked (mapName, &error); + if (mono_error_set_pending_exception (&error)) + return NULL; if (path) { - MmapHandle *handle; - 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) { *ioerror = FILE_ALREADY_EXISTS; handle = NULL; } else { - 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); + char *c_path = mono_string_to_utf8_checked (path, &error); + if (is_ok (&error)) { + handle = (MmapHandle *)open_file_map (c_path, -1, mode, capacity, access, options, ioerror); + if (handle) { + handle->name = g_strdup (c_mapName); + g_hash_table_insert (named_regions, handle->name, handle); + } + } else { + handle = NULL; } + g_free (c_path); } named_regions_unlock (); + } else + handle = open_memory_map (c_mapName, mode, capacity, access, options, ioerror); - g_free (c_mapName); - return handle; - } - - return open_memory_map (mapName, mode, capacity, access, options, ioerror); + g_free (c_mapName); + return handle; } +/* this is an icall */ void * mono_mmap_open_handle (void *input_fd, MonoString *mapName, gint64 *capacity, int access, int options, int *ioerror) { @@ -426,7 +435,8 @@ mono_mmap_open_handle (void *input_fd, MonoString *mapName, gint64 *capacity, in 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_checked (mapName, &error); - mono_error_raise_exception (&error); /* FIXME don't raise here */ + if (mono_error_set_pending_exception (&error)) + return NULL; named_regions_lock (); handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName); @@ -498,8 +508,11 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma struct stat buf = { 0 }; fstat (fh->fd, &buf); //FIXME error handling + *mmap_handle = NULL; + *base_address = NULL; + if (offset > buf.st_size || ((eff_size + offset) > buf.st_size && !is_special_zero_size_file (&buf))) - goto error; + return ACCESS_DENIED; /** * We use the file size if one of the following conditions is true: * -input size is zero @@ -521,9 +534,6 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma return 0; } -error: - *mmap_handle = NULL; - *base_address = NULL; return COULD_NOT_MAP_MEMORY; }