internal static void FeedOutputBuilder(SandboxedProcessOutputBuilder output, string line) { if (line != null) { output.AppendLine(line); } }
internal override void FeedStdErr(SandboxedProcessOutputBuilder builder, TaskSourceSlim <Unit> tsc, string line) { if (line == null) // designates EOF { // extract cpu times from the last recorder line (which should be the output of /usr/bin/time) m_cpuTimes = ExtractCpuTimes(m_lastStdErrLine, out string unprocessedFragment); // feed whatever wasn't consumed FeedOutputBuilder(builder, tsc, unprocessedFragment); // feed EOF FeedOutputBuilder(builder, tsc, null); } else { // feed previous line (if any) if (m_lastStdErrLine != null) { FeedOutputBuilder(builder, tsc, m_lastStdErrLine); } // update previous line m_lastStdErrLine = line; } }
public void Dispose() { using (m_queryJobDataLock.AcquireWriteLock()) { // Prevent further data queries m_disposeStarted = true; } if (m_processStarted) { InternalKill(); m_resultTaskCompletionSource.Task.Wait(); } m_detouredProcess?.Dispose(); m_detouredProcess = null; m_output?.Dispose(); m_output = null; m_error?.Dispose(); m_error = null; m_reports = null; m_fileAccessManifestStreamWrapper.Dispose(); }
private static void FeedOutputBuilder(SandboxedProcessOutputBuilder output, TaskSourceSlim <Unit> signalCompletion, string line) { output.AppendLine(line); if (line == null) { signalCompletion.TrySetResult(Unit.Void); } }
internal static void FeedOutputBuilder(SandboxedProcessOutputBuilder output, TaskSourceSlim <Unit> signalCompletion, string line) { if (signalCompletion.Task.IsCompleted) { return; } output.AppendLine(line); if (line == null) { signalCompletion.TrySetResult(Unit.Void); } }
/// <remarks> /// IMPORTANT: For memory efficiency reasons don't keep a reference to <paramref name="info"/> /// or its <see cref="SandboxedProcessInfo.FileAccessManifest"/> property /// (at least not after the process has been started) /// </remarks> public UnsandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); Started = false; PathTable = info.PathTable; LoggingContext = info.LoggingContext; PipDescription = info.PipDescription; PipSemiStableHash = info.PipSemiStableHash; TimeoutDumpDirectory = info.TimeoutDumpDirectory; ShouldReportFileAccesses = info.FileAccessManifest?.ReportFileAccesses == true; info.Timeout = info.Timeout ?? DefaultProcessTimeout; m_output = new SandboxedProcessOutputBuilder( info.StandardOutputEncoding ?? Console.OutputEncoding, info.MaxLengthInMemory, info.FileStorage, SandboxedProcessFile.StandardOutput, info.StandardOutputObserver); m_error = new SandboxedProcessOutputBuilder( info.StandardErrorEncoding ?? Console.OutputEncoding, info.MaxLengthInMemory, info.FileStorage, SandboxedProcessFile.StandardError, info.StandardErrorObserver); m_processExecutor = new AsyncProcessExecutor( CreateProcess(info), info.Timeout ?? DefaultProcessTimeout, line => FeedStdOut(m_output, line), line => FeedStdErr(m_error, line), info.Provenance, msg => LogProcessState(msg)); if (info.ProcessIdListener != null) { ProcessStarted += (pid) => info.ProcessIdListener(pid); } }
/// <nodoc /> public UnsandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); info.Timeout = info.Timeout ?? DefaultProcessTimeout; ProcessInfo = info; m_output = new SandboxedProcessOutputBuilder( ProcessInfo.StandardOutputEncoding ?? Console.OutputEncoding, ProcessInfo.MaxLengthInMemory, ProcessInfo.FileStorage, SandboxedProcessFile.StandardOutput, ProcessInfo.StandardOutputObserver); m_error = new SandboxedProcessOutputBuilder( ProcessInfo.StandardErrorEncoding ?? Console.OutputEncoding, ProcessInfo.MaxLengthInMemory, ProcessInfo.FileStorage, SandboxedProcessFile.StandardError, ProcessInfo.StandardErrorObserver); }
public void Dispose() { if (m_processStarted) { InternalKill(); m_resultTaskCompletionSource.Task.Wait(); } m_detouredProcess?.Dispose(); m_detouredProcess = null; m_output?.Dispose(); m_output = null; m_error?.Dispose(); m_error = null; m_reports = null; m_fileAccessManifestStreamWrapper.Dispose(); }
/// <nodoc /> public UnSandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); info.Timeout = info.Timeout ?? TimeSpan.FromMinutes(10); ProcessInfo = info; m_output = new SandboxedProcessOutputBuilder( ProcessInfo.StandardOutputEncoding ?? Console.OutputEncoding, ProcessInfo.MaxLengthInMemory, ProcessInfo.FileStorage, SandboxedProcessFile.StandardOutput, ProcessInfo.StandardOutputObserver); m_error = new SandboxedProcessOutputBuilder( ProcessInfo.StandardErrorEncoding ?? Console.OutputEncoding, ProcessInfo.MaxLengthInMemory, ProcessInfo.FileStorage, SandboxedProcessFile.StandardError, ProcessInfo.StandardErrorObserver); Completion = Task.WhenAll(m_processExitedTcs.Task, m_stdoutFlushedTcs.Task, m_stderrFlushedTcs.Task); }
internal virtual void FeedStdErr(SandboxedProcessOutputBuilder b, string line) => FeedOutputBuilder(b, line);
internal SandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); Contract.Requires(!info.Timeout.HasValue || info.Timeout.Value <= Process.MaxTimeout); // there could be a race here, but it just doesn't matter if (s_binaryPaths == null) { s_binaryPaths = new BinaryPaths(); // this can take a while; performs I/O } // If unspecified make the injection timeout the DefaultProcessTimeoutInMinutes. Also, make it no less than DefaultProcessTimeoutInMinutes. m_timeoutMins = info.Timeout.HasValue ? ((uint)info.Timeout.Value.TotalMinutes) : SandboxConfiguration.DefaultProcessTimeoutInMinutes; if (m_timeoutMins < SandboxConfiguration.DefaultProcessTimeoutInMinutes) { m_timeoutMins = SandboxConfiguration.DefaultProcessTimeoutInMinutes; } m_fileAccessManifest = info.FileAccessManifest; m_fileAccessManifestStreamWrapper = Pools.MemoryStreamPool.GetInstance(); m_bufferSize = SandboxedProcessInfo.BufferSize; m_allowedSurvivingChildProcessNames = info.AllowedSurvivingChildProcessNames; m_nestedProcessTerminationTimeout = info.NestedProcessTerminationTimeout; m_loggingContext = info.LoggingContext; Encoding inputEncoding = info.StandardInputEncoding ?? Console.InputEncoding; m_standardInputReader = info.StandardInputReader; m_pathTable = info.PathTable; Encoding outputEncoding = info.StandardOutputEncoding ?? Console.OutputEncoding; m_output = new SandboxedProcessOutputBuilder( outputEncoding, info.MaxLengthInMemory, info.FileStorage, SandboxedProcessFile.StandardOutput, info.StandardOutputObserver); Encoding errorEncoding = info.StandardErrorEncoding ?? Console.OutputEncoding; m_error = new SandboxedProcessOutputBuilder( errorEncoding, info.MaxLengthInMemory, info.FileStorage, SandboxedProcessFile.StandardError, info.StandardErrorObserver); m_reports = m_fileAccessManifest != null ? new SandboxedProcessReports( m_fileAccessManifest, info.PathTable, info.PipSemiStableHash, info.PipDescription, info.LoggingContext, info.DetoursEventListener, info.SidebandWriter) : null; Contract.Assume(inputEncoding != null); Contract.Assert(errorEncoding != null); Contract.Assert(outputEncoding != null); m_detouredProcess = new DetouredProcess( SandboxedProcessInfo.BufferSize, info.GetCommandLine(), info.WorkingDirectory, info.GetUnicodeEnvironmentBlock(), inputEncoding, errorEncoding, m_error.AppendLine, outputEncoding, m_output.AppendLine, OnProcessExitingAsync, OnProcessExited, info.Timeout, info.DisableConHostSharing, info.LoggingContext, info.TimeoutDumpDirectory, info.ContainerConfiguration, // If there is any process configured to breakway from the sandbox, then we need to allow // this to happen at the job object level setJobBreakawayOk: m_fileAccessManifest.ProcessesCanBreakaway, info.CreateJobObjectForCurrentProcess); }
internal virtual void FeedStdErr(SandboxedProcessOutputBuilder b, TaskSourceSlim <Unit> tsc, string line) => FeedOutputBuilder(b, tsc, line);
internal SandboxedProcess(SandboxedProcessInfo info) { Contract.Requires(info != null); Contract.Requires(!info.Timeout.HasValue || info.Timeout.Value <= Process.MaxTimeout); // there could be a race here, but it just doesn't matter if (s_binaryPaths == null) { s_binaryPaths = new BinaryPaths(); // this can take a while; performs I/O } // If unspecified make the injection timeout 10 mins. Also, make it no less than 10 mins. m_timeoutMins = info.Timeout.HasValue ? ((uint)info.Timeout.Value.TotalMinutes) : 10; if (m_timeoutMins < 10) { m_timeoutMins = 10; } m_fileAccessManifest = info.FileAccessManifest; m_fileAccessManifestStreamWrapper = Pools.MemoryStreamPool.GetInstance(); m_bufferSize = SandboxedProcessInfo.BufferSize; m_nestedProcessTerminationTimeout = info.NestedProcessTerminationTimeout; Encoding inputEncoding = info.StandardInputEncoding ?? Console.InputEncoding; m_standardInputReader = info.StandardInputReader; m_pathTable = info.PathTable; Encoding outputEncoding = info.StandardOutputEncoding ?? Console.OutputEncoding; m_output = new SandboxedProcessOutputBuilder( outputEncoding, info.MaxLengthInMemory, info.FileStorage, SandboxedProcessFile.StandardOutput, info.StandardOutputObserver); Encoding errorEncoding = info.StandardErrorEncoding ?? Console.OutputEncoding; m_error = new SandboxedProcessOutputBuilder( errorEncoding, info.MaxLengthInMemory, info.FileStorage, SandboxedProcessFile.StandardError, info.StandardErrorObserver); m_reports = m_fileAccessManifest != null ? new SandboxedProcessReports( m_fileAccessManifest, info.PathTable, info.PipSemiStableHash, info.PipDescription, info.LoggingContext, info.DetoursEventListener) : null; Contract.Assume(inputEncoding != null); Contract.Assert(errorEncoding != null); Contract.Assert(outputEncoding != null); m_processIdListener = info.ProcessIdListener; m_detouredProcess = new DetouredProcess( SandboxedProcessInfo.BufferSize, info.GetCommandLine(), info.WorkingDirectory, info.GetUnicodeEnvironmentBlock(), inputEncoding, errorEncoding, m_error.AppendLine, outputEncoding, m_output.AppendLine, OnProcessExitingAsync, OnProcessExited, info.Timeout, info.DisableConHostSharing, info.LoggingContext, info.TimeoutDumpDirectory); }
internal override void FeedStdErr(SandboxedProcessOutputBuilder builder, string line) { FeedOutputBuilder(builder, line); }