Ensure that CodeDom generated temporary directory is always created. Fixes #12202
authorMarek Safar <marek.safar@gmail.com>
Thu, 10 Oct 2013 09:22:03 +0000 (11:22 +0200)
committerMarek Safar <marek.safar@gmail.com>
Thu, 10 Oct 2013 09:54:20 +0000 (11:54 +0200)
mcs/class/System/System.CodeDom.Compiler/TempFileCollection.cs
mcs/class/System/Test/Microsoft.CSharp/CSharpCodeProviderTest.cs

index da056d15336030f5a974515f73f1cbf02cb7ed4c..3df72ad203a364ee7a6d8281d33557b669f0dad8 100644 (file)
@@ -73,33 +73,36 @@ namespace System.CodeDom.Compiler {
 
                                        // note: this property *cannot* change TempDir property
                                        string temp = tempdir;
-                                       if (temp.Length == 0)
-                                               temp = GetOwnTempDir ();
+                                       if (temp.Length == 0) {
+                                               if (ownTempDir != null) {
+                                                       temp = ownTempDir;
+                                                       Directory.CreateDirectory (temp);
+                                               } else {
+                                                       temp = CreateOwnTempDir ();
+                                               }
+                                       }
 
                                        // Create a temporary file at the target directory. This ensures
                                        // that the generated file name is unique.
-                                       FileStream f = null;
-                                       do {
+                                       int test_counter = 1000;
+                                       while (true) {
                                                int num = rnd.Next ();
                                                num++;
                                                basepath = Path.Combine (temp, num.ToString("x"));
                                                string path = basepath + ".tmp";
 
                                                try {
-                                                       f = new FileStream (path, FileMode.CreateNew);
-                                               }
-                                               catch (System.IO.IOException) {
-                                                       f = null;
-                                                       continue;
-                                               }
-                                               catch {
-                                                       // avoid endless loop
+                                                       using (var f = new FileStream (path, FileMode.CreateNew)) {
+                                                               break;
+                                                       }
+                                               } catch (IOException) {
+                                                       if (test_counter-- > 0)
+                                                               continue;
+
                                                        throw;
                                                }
-                                       } while (f == null);
-                                       
-                                       f.Close ();
-                                       
+                                       }
+
                                        // and you must have discovery access to the combined path
                                        // note: the cache behaviour is tested in the CAS tests
                                        if (SecurityManager.SecurityEnabled) {
@@ -110,12 +113,9 @@ namespace System.CodeDom.Compiler {
                                return(basepath);
                        }
                }
-               
-               string GetOwnTempDir ()
-               {
-                       if (ownTempDir != null)
-                               return ownTempDir;
 
+               string CreateOwnTempDir ()
+               {
                        // this call ensure the Environment permissions check
                        string basedir = Path.GetTempPath ();
                        
@@ -247,7 +247,6 @@ namespace System.CodeDom.Compiler {
                        }
                        if (allDeleted && ownTempDir != null) {
                                Directory.Delete (ownTempDir, true);
-                               ownTempDir = null;
                        }
                }
 
index f34bcca6d6abec884a114ec3cf946fc6efd471ca..4bbcec89c75409b10b49784e2aa3c2a2e6472af2 100644 (file)
@@ -359,6 +359,32 @@ namespace MonoTests.Microsoft.CSharp
                        Assert.AreEqual (tempFile, tempFiles[0], "#5");
                }
 
+
+               [Test]
+               public void CompileFromSource_InMemory_Twice ()
+               {
+                       CompilerParameters options = new CompilerParameters ();
+                       options.GenerateExecutable = false;
+                       options.GenerateInMemory = true;
+
+                       ICodeCompiler compiler = _codeProvider.CreateCompiler ();
+
+                       var src_1 = "class X { ";
+
+                       CompilerResults results_1 = compiler.CompileAssemblyFromSource (options, src_1);
+                       var output_1 = options.OutputAssembly;
+
+                       var src_2 = "class X { }";
+
+                       CompilerResults results_2 = compiler.CompileAssemblyFromSource (options, src_2);
+                       var output_2 = options.OutputAssembly;
+
+                       // verify compilation was successful
+                       AssertCompileResults (results_2, true);
+
+                       Assert.AreEqual (output_1, output_2, "#1");
+               }
+
                [Test]
                public void CompileFromSourceBatch_InMemory ()
                {