+2008-04-23 Marek Habersack <mhabersack@novell.com>
+
+ * domain-internals.h: added a declaration of
+ mono_make_shadow_copy.
+
+ * assembly.c (mono_assembly_open_full): shadow copying of
+ assemblies moved to here, so that all the assemblies within the
+ application domain's private binary directories can be
+ processed. Fixes bug #380546
+
+ * appdomain.c (mono_make_shadow_copy): make_shadow_copy renamed to
+ mono_make_shadow_copy and made non-static. The decision whether
+ to shadow-copy an assembly is made based on its location - it's
+ copied if it's in one of the private application domain binary
+ directories and its different to the target file in the shadow
+ directory. Fixes bug #380546
+
2008-04-22 Zoltan Varga <vargaz@gmail.com>
* reflection.c (fixup_method): Handle {Method|Constructor}OnTypeBuilderInst.
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/object.h>
#include <mono/utils/mono-stdlib.h>
#include <mono/utils/mono-io-portability.h>
#ifdef PLATFORM_WIN32
+#include <sys/utime.h>
#include <direct.h>
#endif
#endif
}
-static char *
-make_shadow_copy (const char *filename)
+static gboolean
+private_file_needs_copying (const char *src, struct stat *sbuf_src, char *dest)
+{
+ struct stat sbuf_dest;
+
+ if (stat (src, sbuf_src) == -1 || stat (dest, &sbuf_dest) == -1)
+ return TRUE;
+
+ if (sbuf_src->st_mode == sbuf_dest.st_mode &&
+ sbuf_src->st_size == sbuf_dest.st_size &&
+ sbuf_src->st_mtime == sbuf_dest.st_mtime)
+ return FALSE;
+
+ return TRUE;
+}
+
+char *
+mono_make_shadow_copy (const char *filename)
{
gchar *sibling_source, *sibling_target;
gint sibling_source_len, sibling_target_len;
guint16 *orig, *dest;
char *shadow;
gboolean copy_result;
+ gboolean is_private = FALSE;
+ gboolean do_copy = FALSE;
MonoException *exc;
+ gchar **path;
+ struct stat src_sbuf;
+ struct utimbuf utbuf;
+ char *dir_name = g_path_get_dirname (filename);
+ MonoDomain *domain = mono_domain_get ();
+ set_domain_search_path (domain);
+
+ if (!domain->search_path)
+ return (char*) filename;
+
+ for (path = domain->search_path; *path; path++) {
+ if (**path == '\0') {
+ is_private = TRUE;
+ continue;
+ }
+
+ if (!is_private)
+ continue;
+
+ if (strcmp (dir_name, *path) == 0) {
+ do_copy = TRUE;
+ break;
+ }
+ }
+
+ if (!do_copy)
+ return (char*) filename;
shadow = get_shadow_assembly_location (filename);
if (ensure_directory_exists (shadow) == FALSE) {
mono_raise_exception (exc);
}
+ if (!private_file_needs_copying (filename, &src_sbuf, shadow))
+ return (char*) shadow;
+
orig = g_utf8_to_utf16 (filename, strlen (filename), NULL, NULL, NULL);
dest = g_utf8_to_utf16 (shadow, strlen (shadow), NULL, NULL, NULL);
DeleteFile (dest);
exc = mono_get_exception_execution_engine ("Failed to create shadow copy of sibling data (CopyFile).");
mono_raise_exception (exc);
}
+
+ utbuf.actime = src_sbuf.st_atime;
+ utbuf.modtime = src_sbuf.st_mtime;
+ utime (shadow, &utbuf);
return shadow;
}
} else
found = g_file_test (fullpath, G_FILE_TEST_IS_REGULAR);
- if (found) {
- if (is_private) {
- char *new_path = make_shadow_copy (fullpath);
- g_free (fullpath);
- fullpath = new_path;
- }
-
+ if (found)
*assembly = mono_assembly_open_full (fullpath, NULL, refonly);
- }
g_free (fullpath);
return (*assembly != NULL);
}
name = filename = mono_string_to_utf8 (fname);
-
+
ass = mono_assembly_open_full (filename, &status, refOnly);
if (!ass){
MonoAssembly *ass;
MonoImageOpenStatus def_status;
gchar *fname;
+ gchar *new_fname;
g_return_val_if_fail (filename != NULL, NULL);
}
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY,
- "Assembly Loader probing location: '%s'.", filename);
+ "Assembly Loader probing location: '%s'.", fname);
+ new_fname = mono_make_shadow_copy (fname);
+ if (new_fname && new_fname != fname) {
+ g_free (fname);
+ fname = new_fname;
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY,
+ "Assembly Loader shadow-copied assembly to: '%s'.", fname);
+ }
+
image = NULL;
if (bundles != NULL)