2008-04-23 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Wed, 23 Apr 2008 12:49:57 +0000 (12:49 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Wed, 23 Apr 2008 12:49:57 +0000 (12:49 -0000)
* 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

svn path=/trunk/mono/; revision=101539

mono/metadata/ChangeLog
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/domain-internals.h

index 3c39945fbfd4feeb3fb5e24af764471dd525efb4..f09f78764d627271683bc8d51024505ad3b86bae 100644 (file)
@@ -1,3 +1,20 @@
+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.
index c63d7ad4ba40ed937a525a42b06c460bd5758a5f..0200ed2d79f9b2b596caacef109bd7c0cadeed64 100644 (file)
@@ -18,6 +18,9 @@
 #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>
@@ -40,6 +43,7 @@
 #include <mono/utils/mono-stdlib.h>
 #include <mono/utils/mono-io-portability.h>
 #ifdef PLATFORM_WIN32
+#include <sys/utime.h>
 #include <direct.h>
 #endif
 
@@ -1119,15 +1123,60 @@ ensure_directory_exists (const char *filename)
 #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) {
@@ -1135,6 +1184,9 @@ make_shadow_copy (const char *filename)
                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);
@@ -1166,6 +1218,10 @@ make_shadow_copy (const char *filename)
                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;
 }
@@ -1191,15 +1247,8 @@ try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2,
        } 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);
@@ -1325,7 +1374,7 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean re
        }
                
        name = filename = mono_string_to_utf8 (fname);
-
+       
        ass = mono_assembly_open_full (filename, &status, refOnly);
        
        if (!ass){
index 0314d2e585d0c7e443df5c6d57bd1388de16f02b..7278b6e4755c3fff9efbaa50cb06552898401b8b 100644 (file)
@@ -1253,6 +1253,7 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
        MonoAssembly *ass;
        MonoImageOpenStatus def_status;
        gchar *fname;
+       gchar *new_fname;
        
        g_return_val_if_fail (filename != NULL, NULL);
 
@@ -1290,7 +1291,15 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
        }
 
        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)
index 3a75d4c8bbed9c015ecfc0632778af4fb473e9b4..f4653190b359b13aa80fd65a639c10416b54b484 100644 (file)
@@ -248,6 +248,8 @@ mono_domain_lookup_shared_generic (MonoDomain *domain, MonoMethod *method) MONO_
 void
 mono_domain_register_shared_generic (MonoDomain *domain, MonoMethod *method, MonoJitInfo *jit_info) MONO_INTERNAL;
 
+char *
+mono_make_shadow_copy (const char *filename);
 
 /* 
  * Installs a new function which is used to return a MonoJitInfo for a method inside