예제 #1
0
        static void ExecuteCode(string nr, string input)
        {
            try
            {
                string path = @"C:\inetpub\wwwroot\rextester\usercode\";
                Console.WriteLine("Sandbox start: " + nr);
                using (Process process = new Process())
                    using (var job = new Job())
                    {
                        process.StartInfo.FileName = Path.Combine(path, nr, "a.exe");

                        Console.WriteLine(process.StartInfo.FileName);

                        process.StartInfo.UseShellExecute        = false;
                        process.StartInfo.CreateNoWindow         = true;
                        process.StartInfo.RedirectStandardError  = true;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.RedirectStandardInput  = true;

                        Console.WriteLine("Sandbox: job start " + nr);

                        process.Start();
                        job.AddProcess(process.Handle);

                        if (!string.IsNullOrEmpty(input))
                        {
                            InputWriter iw          = new InputWriter(process.StandardInput, input);
                            Thread      inputWriter = new Thread(new ThreadStart(iw.Writeinput));
                            inputWriter.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();

                        var    start  = DateTime.Now;
                        bool   killed = false;
                        string Errors = "";
                        string Output = "";

                        do
                        {
                            // Refresh the current process property values.
                            process.Refresh();
                            if (!process.HasExited)
                            {
                                try
                                {
                                    if (start + TimeSpan.FromSeconds(20) < DateTime.Now)
                                    {
                                        process.Kill();
                                        var res = string.Format("Process killed because it ran longer than 20 seconds");
                                        Errors = res;
                                        Output = output.Builder.ToString();
                                        killed = true;
                                    }
                                }
                                catch (InvalidOperationException)
                                {
                                    break;
                                }
                            }
                        }while (!process.WaitForExit(10));
                        process.WaitForExit();

                        Console.WriteLine("Sandbox: job over " + nr);

                        if (!killed)
                        {
                            errorReader.Join(5000);
                            outputReader.Join(5000);

                            if (process.ExitCode != 0)
                            {
                                error.Output = string.Format("Process exit code is not 0: {0}\n", process.ExitCode) + error.Output;
                            }

                            Errors = error.Output;
                            Output = output.Output;
                        }

                        if (!string.IsNullOrEmpty(Errors))
                        {
                            Console.WriteLine("Sandbox: writing errors " + nr);
                            RedisConnection.Strings.Set(3, nr, Encoding.UTF8.GetBytes(Errors));
                        }

                        if (!string.IsNullOrEmpty(Output))
                        {
                            Console.WriteLine("Sandbox: writing output " + nr);
                            RedisConnection.Strings.Set(2, nr, Encoding.UTF8.GetBytes(Output));
                        }

                        RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 });
                    }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Sandbox: error " + nr + " " + ex.Message);
                try
                {
                    RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 });
                }
                catch (Exception) { }
            }
            finally
            {
                //ThreadPool.QueueUserWorkItem(f => {
                //    CleanSandbox();
                //});
            }
        }
예제 #2
0
        static void ExecuteCode(string nr, string input)
        {
            try
            {
                string path = @"C:\inetpub\wwwroot\rextester\usercode\";
                Console.WriteLine("Sandbox start: " + nr);
                using (Process process = new Process())
                using (var job = new Job())
                {
                    process.StartInfo.FileName = Path.Combine(path, nr, "a.exe");

                    Console.WriteLine(process.StartInfo.FileName);

                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.CreateNoWindow = true;
                    process.StartInfo.RedirectStandardError = true;
                    process.StartInfo.RedirectStandardOutput = true;
                    process.StartInfo.RedirectStandardInput = true;

                    Console.WriteLine("Sandbox: job start " + nr);

                    process.Start();
                    job.AddProcess(process.Handle);

                    if (!string.IsNullOrEmpty(input))
                    {
                        InputWriter iw = new InputWriter(process.StandardInput, input);
                        Thread inputWriter = new Thread(new ThreadStart(iw.Writeinput));
                        inputWriter.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();

                    var start = DateTime.Now;
                    bool killed = false;
                    string Errors = "";
                    string Output = "";

                    do
                    {
                        // Refresh the current process property values.
                        process.Refresh();
                        if (!process.HasExited)
                        {
                            try
                            {
                                if (start + TimeSpan.FromSeconds(20) < DateTime.Now)
                                {
                                    process.Kill();
                                    var res = string.Format("Process killed because it ran longer than 20 seconds");
                                    Errors = res;
                                    Output = output.Builder.ToString();
                                    killed = true;
                                }
                            }
                            catch (InvalidOperationException)
                            {
                                break;
                            }
                        }
                    }
                    while (!process.WaitForExit(10));
                    process.WaitForExit();

                    Console.WriteLine("Sandbox: job over " + nr);

                    if (!killed)
                    {
                        errorReader.Join(5000);
                        outputReader.Join(5000);

                        if (process.ExitCode != 0)
                            error.Output = string.Format("Process exit code is not 0: {0}\n", process.ExitCode) + error.Output;

                        Errors = error.Output;
                        Output = output.Output;
                    }

                    if (!string.IsNullOrEmpty(Errors))
                    {
                        Console.WriteLine("Sandbox: writing errors " + nr);
                        RedisConnection.Strings.Set(3, nr, Encoding.UTF8.GetBytes(Errors));
                    }

                    if (!string.IsNullOrEmpty(Output))
                    {
                        Console.WriteLine("Sandbox: writing output " + nr);
                        RedisConnection.Strings.Set(2, nr, Encoding.UTF8.GetBytes(Output));
                    }

                    RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Sandbox: error " + nr + " " + ex.Message);
                try
                {
                    RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 });
                }
                catch (Exception) { }

            }
            finally
            {
                //ThreadPool.QueueUserWorkItem(f => {
                //    CleanSandbox();
                //});
            }
        }