Exemple #1
0
void *
mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
{
	g_assert (path || mapName);

	if (!mapName)
		return open_file_map (path, -1, mode, capacity, access, options, error);

	if (path) {
		MmapHandle *handle;
		char *c_mapName = mono_string_to_utf8 (mapName);

		named_regions_lock ();
		handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
		if (handle) {
			*error = FILE_ALREADY_EXISTS;
			handle = NULL;
		} else {
			handle = open_file_map (path, -1, mode, capacity, access, options, error);
			if (handle) {
				handle->name = g_strdup (c_mapName);
				g_hash_table_insert (named_regions, handle->name, handle);
			}
		}
		named_regions_unlock ();

		g_free (c_mapName);
		return handle;
	}

	return open_memory_map (mapName, mode, capacity, access, options, error);
}
/* this is an icall */
void *
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, ioerror);
	} else {
		char *c_mapName = mono_string_to_utf8_checked (mapName, &error);
		if (mono_error_set_pending_exception (&error))
			return NULL;

		named_regions_lock ();
		handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
		if (handle) {
			*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, ioerror);
			handle->name = g_strdup (c_mapName);
			g_hash_table_insert (named_regions, handle->name, handle);
		}
		named_regions_unlock ();

		g_free (c_mapName);
	}
	return handle;
}
Exemple #3
0
void
mono_mmap_close (void *mmap_handle)
{
	MmapHandle *handle = mmap_handle;

	named_regions_lock ();
	--handle->ref_count;
	if (handle->ref_count == 0) {
		if (handle->name)
			g_hash_table_remove (named_regions, handle->name);

		g_free (handle->name);
		close (handle->fd);
		g_free (handle);
	}
	named_regions_unlock ();
}
/* 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) {
		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) {
		named_regions_lock ();
		handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
		if (handle) {
			*ioerror = FILE_ALREADY_EXISTS;
			handle = NULL;
		} else {
			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;
}
Exemple #5
0
static void*
open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *error)
{
	char *c_mapName;
	MmapHandle *handle;
	if (*capacity <= 1) {
		*error = 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;
		return NULL;
	}

	c_mapName = mono_string_to_utf8 (mapName);

	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;
			goto done;
		}

		handle->ref_count++;
		//XXX should we ftruncate if the file is smaller than capacity?
	} else {
		int fd;
		char file_name [sizeof (MONO_ANON_FILE_TEMPLATE) + 1];
		int unused G_GNUC_UNUSED;

		if (mode == FILE_MODE_OPEN) {
			*error = FILE_NOT_FOUND;
			goto done;
		}
		*capacity = align_up_to_page_size (*capacity);

		strcpy (file_name, MONO_ANON_FILE_TEMPLATE);
		fd = mkstemp (file_name);
		if (fd == -1) {
			*error = COULD_NOT_MAP_MEMORY;
			goto done;
		}

		unlink (file_name);
		unused = ftruncate (fd, (off_t)*capacity);

		handle = g_new0 (MmapHandle, 1);
		handle->ref_count = 1;
		handle->capacity = *capacity;
		handle->fd = fd;
		handle->name = g_strdup (c_mapName);

		g_hash_table_insert (named_regions, handle->name, handle);

	}

done:
	named_regions_unlock ();

	g_free (c_mapName);
	return handle;
}
static void*
open_memory_map (const char *c_mapName, int mode, gint64 *capacity, int access, int options, int *ioerror)
{
	MmapHandle *handle;
	if (*capacity <= 0) {
		*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;
	}

	named_regions_lock ();
	handle = (MmapHandle*)g_hash_table_lookup (named_regions, c_mapName);
	if (handle) {
		if (mode == FILE_MODE_CREATE_NEW) {
			*ioerror = FILE_ALREADY_EXISTS;
			goto done;
		}

		handle->ref_count++;
		//XXX should we ftruncate if the file is smaller than capacity?
	} else {
		int fd;
		char *file_name;
		const char *tmp_dir;
		int unused G_GNUC_UNUSED, alloc_size;

		if (mode == FILE_MODE_OPEN) {
			*ioerror = FILE_NOT_FOUND;
			goto done;
		}
		*capacity = align_up_to_page_size (*capacity);

		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
			*ioerror = COULD_NOT_MAP_MEMORY;
			goto done;
		}
		file_name = (char *)alloca (alloc_size);
		strcpy (file_name, tmp_dir);
		strcat (file_name, MONO_ANON_FILE_TEMPLATE);

		fd = mkstemp (file_name);
		if (fd == -1) {
			*ioerror = COULD_NOT_MAP_MEMORY;
			goto done;
		}

		unlink (file_name);
		unused = ftruncate (fd, (off_t)*capacity);

		handle = g_new0 (MmapHandle, 1);
		handle->ref_count = 1;
		handle->capacity = *capacity;
		handle->fd = fd;
		handle->name = g_strdup (c_mapName);

		g_hash_table_insert (named_regions, handle->name, handle);

	}

done:
	named_regions_unlock ();

	return handle;
}