Ejemplo n.º 1
0
        /// <summary>
        /// Attempts to start the process and returns a task that is completed when the process
        /// exits with an exit code of zero (success). Standard output and error output are
        /// captured.
        /// </summary>
        /// <returns>A task evaluates to the output of the process.</returns>
        /// <exception cref="ProcessException">
        /// Thrown if the process cannot be started, or if it does not exit within the timeout
        /// period that was specified when the process was created.
        /// </exception>
        /// <exception cref="ProcessExecutionException">
        /// Thrown if the process exits with a non-zero exit code. Use the OutputLines and
        /// ErrorLines properties to get the process output and error text, respectively.
        /// </exception>
        public static async Task <List <string> > RunToExitWithSuccessCapturingOutputAsync(
            this IProcess process)
        {
            List <string> outputLines = new List <string>();
            List <string> errorLines  = new List <string>();

            process.OutputDataReceived += (obj, args) =>
            {
                if (args.Text != null)
                {
                    outputLines.Add(args.Text);
                }
            };
            process.ErrorDataReceived += (obj, args) =>
            {
                if (args.Text != null)
                {
                    errorLines.Add(args.Text);
                }
            };

            var code = await process.RunToExitAsync();

            if (code != 0)
            {
                throw new ProcessExecutionException(
                          ErrorStrings.ProcessExitedWithErrorCode(process.ProcessName, code),
                          code, outputLines, errorLines);
            }
            return(outputLines);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Checks exit code of the process. If it is non-zero it throws
 /// the ProcessExecutionException.
 /// </summary>
 /// <exception cref="ProcessExecutionException">
 /// Thrown if the process exits with a non-zero exit code.
 /// </exception>
 /// <param name="code">Exit code of the process.</param>
 public static void CheckExitCode(this IProcess process, int code)
 {
     if (code != 0)
     {
         throw new ProcessExecutionException(
                   ErrorStrings.ProcessExitedWithErrorCode(process.ProcessName, code), code);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Parses an elf binary or symbol file and returns the build ID encoded
        /// in the .note.gnu.build-id section of the file.
        /// </summary>
        /// <param name="filepath">The local or remote absolute file path.</param>
        /// <param name="target">Optional parameter specifying the remote gamelet.</param>
        /// <returns>A non-empty build id.</returns>
        /// <exception cref="BinaryFileUtilException">
        /// Thrown when an error is encountered reading or parsing the build id.
        /// InnerException contains more details.
        /// </exception>
        public async Task <BuildId> ReadBuildIdAsync(string filepath, SshTarget target = null)
        {
            try
            {
                var outputLines = await ReadSectionFromFileAsync(".note.gnu.build-id", filepath,
                                                                 target);

                var hexString = ParseHexDump(outputLines);
                var result    = ParseBuildIdOutput(hexString);
                if (result == BuildId.Empty)
                {
                    throw new InvalidBuildIdException(
                              ErrorStrings.FailedToReadBuildId(filepath,
                                                               ErrorStrings.EmptyBuildId));
                }
                return(result);
            }
            catch (ProcessExecutionException e)
            {
                LogObjdumpOutput(e);

                // objdump returned an error code, possibly because the file being parsed is not
                // actually an elf file. With an SSH target, exit code 255 means SSH failed before
                // it had a chance to execute the remote command.
                if (target != null && e.ExitCode < 255)
                {
                    // The remote command failed, so we need to fix the exception message.
                    // TODO: ManagedProcess should report the remote filename.
                    throw new BinaryFileUtilException(
                              ErrorStrings.FailedToReadBuildId(
                                  filepath, ErrorStrings.ProcessExitedWithErrorCode(
                                      YetiConstants.ObjDumpLinuxExecutable, e.ExitCode)),
                              e);
                }
                else
                {
                    throw new BinaryFileUtilException(
                              ErrorStrings.FailedToReadBuildId(filepath, e.Message), e);
                }
            }
            catch (ProcessException e)
            {
                // objdump failed to launch, possibly because the SDK was not found. With an SSH
                // target, this indicates that SSH failed to launch. In either case, the specific
                // filepath was never accessed, so it is not part of the error.
                throw new BinaryFileUtilException(
                          ErrorStrings.FailedToReadBuildId(e.Message), e);
            }
            catch (FormatException e)
            {
                // Indicates the build ID section is malformed.
                throw new InvalidBuildIdException(
                          ErrorStrings.FailedToReadBuildId(
                              filepath, ErrorStrings.MalformedBuildID),
                          e);
            }
        }