static void TestEngineDirectly(string Program, string Input, Languages Lang, string Args = null) { Engine engine = new Engine(); InputData idata = new InputData() { Program = Program, Input = Input, Lang = Lang, Compiler_args = Args }; var odata = engine.DoWork(idata); ShowData(odata); }
public Result DoWork(string Program, string Input, Languages Language, string user, string pass, string compiler_args = "", bool bytes = false, bool programCompressed = false, bool inputCompressed = false) { if (user != GlobalUtils.TopSecret.Service_user || pass != GlobalUtils.TopSecret.Service_pass) { return new Result() { Errors = null, Warnings = null, Output = null, Stats = null, Exit_Status = null, Exit_Code = null, System_Error = "Not authorized." }; } if (programCompressed) Program = GlobalUtils.Utils.Decompress(Program); if (inputCompressed) Input = GlobalUtils.Utils.Decompress(Input); Engine engine = new Engine(); InputData idata = new InputData() { Program = Program, Input = Input, Lang = Language, Compiler_args = compiler_args }; var odata = engine.DoWork(idata); Regex r = new Regex(engine.RootPath.Replace(@"\", @"\\") + @"\d+\\", RegexOptions.IgnoreCase); if (!string.IsNullOrEmpty(odata.Output)) odata.Output = r.Replace(odata.Output, ""); Regex r2 = new Regex(engine.RootPath.Replace(@"\", @"\\") + @"\d+\\\d+", RegexOptions.IgnoreCase); var res = new Result() { Errors = !string.IsNullOrEmpty(odata.Errors) ? r.Replace(r2.Replace(odata.Errors, "source_file"), "") : odata.Errors, Warnings = !string.IsNullOrEmpty(odata.Warnings) ? r.Replace(r2.Replace(odata.Warnings, "source_file"), "") : odata.Warnings, Output = odata.Output, Stats = odata.Stats, Exit_Status = odata.Exit_Status, Exit_Code = odata.ExitCode, System_Error = odata.System_Error, Files = odata.Files }; if (!string.IsNullOrEmpty(odata.Output) && odata.Output.Length > 1000) { res.Output = GlobalUtils.Utils.Compress(odata.Output); res.IsOutputCompressed = true; } if (bytes) { if (!string.IsNullOrEmpty(res.Errors)) { res.Errors_Bytes = System.Text.Encoding.Unicode.GetBytes(res.Errors); res.Errors = null; } if (!string.IsNullOrEmpty(res.Warnings)) { res.Warnings_Bytes = System.Text.Encoding.Unicode.GetBytes(res.Warnings); res.Warnings = null; } if (!string.IsNullOrEmpty(res.Output)) { res.Output_Bytes = System.Text.Encoding.Unicode.GetBytes(res.Output); res.Output = null; } } return res; }
OutputData RunVC(InputData idata) { CompilerData cdata = null; try { OutputData odata = new OutputData(); cdata = CreateExecutable(idata); if (!cdata.Success) { odata.Errors = cdata.Error; odata.Warnings = cdata.Warning; odata.Stats = string.Format("Compilation time: {0} sec", Math.Round((double)cdata.CompileTimeMs / (double)1000, 2)); return odata; } if (!string.IsNullOrEmpty(cdata.Warning)) { odata.Warnings = cdata.Warning; } Stopwatch watch = new Stopwatch(); watch.Start(); string nr = cdata.Rand; if (!string.IsNullOrEmpty(idata.Input)) { RedisConnection.Strings.Set(1, nr, Encoding.UTF8.GetBytes(idata.Input)); } RedisConnection.Strings.Set(0, nr, new byte[] { (byte)1 }); for (int i = 400; i > 0; i--) { Thread.Sleep(100); bool _break = false; var res = RedisConnection.Strings.Get(4, nr).Result; if (res != null) { _break = true; var output = RedisConnection.Strings.Get(2, nr).Result; if (output != null) { odata.Output = Encoding.UTF8.GetString(output); var a = RedisConnection.Keys.Remove(2, nr).Result; } var errors = RedisConnection.Strings.Get(3, nr).Result; if (errors != null) { odata.Errors = Encoding.UTF8.GetString(errors); var a = RedisConnection.Keys.Remove(3, nr).Result; } } if (_break) { break; } } watch.Stop(); if (Utils.IsCompiled(idata.Lang)) { //odata.Stats = string.Format("Compilation time: {0} sec, absolute running time: {1} sec, cpu time: {2} sec, memory peak: {3} Mb", Math.Round((double)cdata.CompileTimeMs / (double)1000, 2), Math.Round((double)watch.ElapsedMilliseconds / (double)1000, 2), Math.Round(CpuTimeInSec, 2), MemoryPickInKilobytes / 1024); odata.Stats = string.Format("Compilation time: {0} sec, absolute running time: {1} sec", Math.Round((double)cdata.CompileTimeMs / (double)1000, 2), Math.Round((double)watch.ElapsedMilliseconds / (double)1000, 2)); } else { //odata.Stats = string.Format("Absolute running time: {0} sec, cpu time: {1} sec, memory peak: {2} Mb", Math.Round((double)watch.ElapsedMilliseconds / (double)1000, 2), Math.Round(CpuTimeInSec, 2), MemoryPickInKilobytes / 1024); odata.Stats = string.Format("Absolute running time: {0} sec", Math.Round((double)watch.ElapsedMilliseconds / (double)1000, 2)); } return odata; } catch (Exception ex) { return new OutputData() { System_Error = ex.Message }; } finally { if (cdata != null) Cleanup(cdata.CleanThis); } }
OutputData RunSql(InputData idata) { OutputData odata = new OutputData(); string path = BasePath + @"usercode\" + Utils.RandomString() + ".sql"; using (TextWriter tw = new StreamWriter(path)) { tw.Write(idata.Program); } using (Process process = new Process()) { try { double TotalMemoryInBytes = 0; double TotalThreadCount = 0; int samplesCount = 0; process.StartInfo.FileName = BasePath + @"executables\SqlSandbox.exe"; process.StartInfo.Arguments = path.Replace(" ", "|_|"); process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; DateTime start = DateTime.Now; process.Start(); OutputReader output = new OutputReader(process.StandardOutput); Thread outputReader = new Thread(new ThreadStart(output.ReadOutput)); outputReader.Start(); OutputReader error = new OutputReader(process.StandardError); Thread errorReader = new Thread(new ThreadStart(error.ReadOutput)); errorReader.Start(); do { // Refresh the current process property values. process.Refresh(); if (!process.HasExited) { try { var proc = process.TotalProcessorTime; // Update the values for the overall peak memory statistics. var mem1 = process.PagedMemorySize64; var mem2 = process.PrivateMemorySize64; //update stats TotalMemoryInBytes += (mem1 + mem2); TotalThreadCount += (process.Threads.Count); samplesCount++; if (proc.TotalSeconds > 5 || mem1 + mem2 > 100000000 || process.Threads.Count > 100 || start + TimeSpan.FromSeconds(15) < DateTime.Now) { var time = proc.TotalSeconds; var mem = mem1 + mem2; process.Kill(); var res = string.Format("Process killed because it exceeded given resources.\nCpu time used {0} sec, absolute running time {1} sec, memory used {2} Mb, nr of threads {3}", time, (int)(DateTime.Now - start).TotalSeconds, (int)(mem / 1048576), process.Threads.Count); odata.Errors = odata.Errors + "\n" + res; string partialResult = output.Builder.ToString(); odata.Output = partialResult; //odata.Stats = string.Format("Absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2)); //Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, res, (int)data.LanguageChoice, data.IsApi); return odata; } } catch (InvalidOperationException) { break; } } } while (!process.WaitForExit(10)); process.WaitForExit(); errorReader.Join(5000); outputReader.Join(5000); if (!string.IsNullOrEmpty(error.Output)) { odata.Output = output.Builder.ToString(); odata.Errors += "\n" + error.Output; odata.Stats = string.Format("Absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2)); //Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, error.Output, (int)data.LanguageChoice, data.IsApi); return odata; } if (File.Exists(path + ".stats")) { using (TextReader tr = new StreamReader(path + ".stats")) { odata.Stats = tr.ReadLine(); if (!string.IsNullOrEmpty(odata.Stats)) odata.Stats += ", "; else odata.Stats = ""; odata.Stats += string.Format("absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2)); } } //else //{ // odata.Stats = string.Format("Absolute service time: {0} sec", Math.Round((double)(DateTime.Now - start).TotalMilliseconds / 1000, 2)); //} odata.Output = output.Output; // Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, "OK", (int)data.LanguageChoice, data.IsApi); return odata; } catch (Exception e) { if (!process.HasExited) { //reExp.Utils.Log.LogInfo("Process left running " + e.Message, "RunSqlServer"); } throw; } finally { try { File.Delete(path); } catch (Exception) { } //SqlServerUtils job = new SqlServerUtils(); //Thread t = new Thread(job.DoShrinkJob); //t.Start(); } } }
CompilerData CreateExecutable(InputData input) { CompilerData cdata = new CompilerData(); string ext = ""; string rand = Utils.RandomString(); cdata.Rand = rand; string dir = rand + @"\"; switch (input.Lang) { case Languages.VCPP: ext = ".cpp"; break; case Languages.VC: ext = ".c"; break; default: ext = ".unknown"; break; } string PathToSource = RootPath + dir + rand + ext; input.PathToSource = PathToSource; input.BaseDir = RootPath + dir; input.Rand = rand; Directory.CreateDirectory(RootPath + dir); Directory.SetCurrentDirectory(RootPath + dir); //DirectorySecurity sec = Directory.GetAccessControl(RootPath + dir); //SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null); //sec.AddAccessRule(new FileSystemAccessRule(everyone, FileSystemRights.Modify | FileSystemRights.Synchronize, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); //Directory.SetAccessControl(RootPath + dir, sec); using (TextWriter sw = new StreamWriter(PathToSource)) { sw.Write(input.Program); } cdata.CleanThis = RootPath + dir; var comp = ICompilerFactory.GetICompiler(input.Lang); if (comp != null) return comp.Compile(input, cdata); cdata.Success = false; return cdata; }
public OutputData DoWork(InputData idata) { if (idata.Lang == Languages.VC || idata.Lang == Languages.VCPP) { return RunVC(idata); } else { return RunSql(idata); } }