/// <inheritdoc /> public override void Start() { base.Start(); SerializeSandboxedProcessInfoToFile(); var process = new Process { StartInfo = new ProcessStartInfo { FileName = m_tool.ExecutablePath, Arguments = m_tool.CreateArguments(SandboxedProcessInfoFile, SandboxedProcessResultsFile), WorkingDirectory = SandboxedProcessInfo.WorkingDirectory, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }, EnableRaisingEvents = true }; m_processExecutor = new AsyncProcessExecutor( process, TimeSpan.FromMilliseconds(-1), // Timeout should only be applied to the process that the external tool executes. line => AppendLineIfNotNull(m_output, line), line => AppendLineIfNotNull(m_error, line), SandboxedProcessInfo.Provenance, message => LogExternalExecution(message)); m_processExecutor.Start(); }
private void RunInVm() { // (1) Serialize sandboxed prosess info. SerializeSandboxedProcessInfoToFile(); // (2) Create and serialize run request. var runRequest = new RunRequest { AbsolutePath = m_tool.ExecutablePath, Arguments = m_tool.CreateArguments(GetSandboxedProcessInfoFile(), GetSandboxedProcessResultsFile()), WorkingDirectory = GetOutputDirectory() }; VmSerializer.SerializeToFile(RunRequestPath, runRequest); // (2) Create a process to execute VmCommandProxy. string arguments = $"{VmCommands.Run} /{VmCommands.Params.InputJsonFile}:\"{RunRequestPath}\" /{VmCommands.Params.OutputJsonFile}:\"{RunOutputPath}\""; var process = CreateVmCommandProxyProcess(arguments); LogExternalExecution($"call (wd: {process.StartInfo.WorkingDirectory}) {m_vmInitializer.VmCommandProxy} {arguments}"); m_processExecutor = new AsyncProcessExecutor( process, TimeSpan.FromMilliseconds(-1), // Timeout should only be applied to the process that the external tool executes. line => AppendLineIfNotNull(m_output, line), line => AppendLineIfNotNull(m_error, line), SandboxedProcessInfo.Provenance, message => LogExternalExecution(message)); m_processExecutor.Start(); }
private void Setup() { SerializeSandboxedProcessInfoToFile(); var process = new Process { StartInfo = new ProcessStartInfo { FileName = m_toolPath, Arguments = CreateArguments(), WorkingDirectory = SandboxedProcessInfo.WorkingDirectory, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }, EnableRaisingEvents = true }; m_processExecutor = new AsyncProcessExecutor( process, TimeSpan.FromMilliseconds(-1), // Timeout should only be applied to the process that the external tool executes. line => AppendLineIfNotNull(m_output, line), line => AppendLineIfNotNull(m_error, line), SandboxedProcessInfo); }
/// <summary> /// Kills process executor. /// </summary> protected Task KillProcessExecutorAsync(AsyncProcessExecutor executor) { Contract.Requires(executor != null); ProcessDumper.TryDumpProcessAndChildren(ProcessId, WorkingDirectory, out DumpCreationException); return(executor.KillAsync()); }
/// <summary> /// Mutates <see cref="Process"/>. /// </summary> protected void CreateAndSetUpProcess() { Contract.Requires(Process == null); #if PLATFORM_OSX var mode = GetFilePermissionsForFilePath(ProcessInfo.FileName, followSymlink: false); if (mode < 0) { ThrowBuildXLException($"Process creation failed: File '{ProcessInfo.FileName}' not found", new Win32Exception(0x2)); } var filePermissions = checked ((FilePermissions)mode); FilePermissions exePermission = FilePermissions.S_IXUSR; if (!filePermissions.HasFlag(exePermission)) { SetFilePermissionsForFilePath(ProcessInfo.FileName, exePermission); } #endif var process = new Process { StartInfo = new ProcessStartInfo { FileName = ProcessInfo.FileName, Arguments = ProcessInfo.Arguments, WorkingDirectory = ProcessInfo.WorkingDirectory, StandardErrorEncoding = m_output.Encoding, StandardOutputEncoding = m_error.Encoding, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }, EnableRaisingEvents = true }; process.StartInfo.EnvironmentVariables.Clear(); if (ProcessInfo.EnvironmentVariables != null) { foreach (var envKvp in ProcessInfo.EnvironmentVariables.ToDictionary()) { process.StartInfo.EnvironmentVariables[envKvp.Key] = envKvp.Value; } } m_processExecutor = new AsyncProcessExecutor( process, ProcessInfo.Timeout ?? TimeSpan.FromMinutes(10), line => FeedStdOut(m_output, line), line => FeedStdErr(m_error, line), ProcessInfo); }
/// <inheritdoc /> public void Start() { Contract.Requires(!Started, "Process was already started. Cannot start process more than once."); m_processExecutor = new AsyncProcessExecutor( CreateProcess(), ProcessInfo.Timeout ?? TimeSpan.FromMinutes(10), line => FeedStdOut(m_output, line), line => FeedStdErr(m_error, line), ProcessInfo, msg => LogProcessState(msg)); m_processExecutor.Start(); ProcessStarted?.Invoke(); ProcessInfo.ProcessIdListener?.Invoke(ProcessId); }
/// <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); } }