private static string? RunLddVersion()

in JetBrains.HabitatDetector/src/Impl/Linux/LinuxHelper.cs [116:163]


    private static string? RunLddVersion(bool shouldFail, string ldd)
    {
#if NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6
      return null;
#else
      // Note(ww898): We can fail whether no ldd on system.
      if (!File.Exists(ldd))
        return null;

      var builder = new StringBuilder();

      void OnDataReceived(string? str)
      {
        if (str != null)
          lock (builder)
            builder.AppendLine(str);
      }

      using (var process = new Process())
      {
        // Note(ww898): MUSL doesn't support `--version` argument, so /usr/bin/ldd dumps version and fail with exit code 1, see https://github.com/kraj/musl/blob/007997299248b8682dcbb73595c53dfe86071c83/ldso/dynlink.c#L1895-L1901
        process.StartInfo = new ProcessStartInfo(ldd, "--version")
          {
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = shouldFail
          };

        process.OutputDataReceived += (_, args) => OnDataReceived(args.Data);
        if (shouldFail)
          process.ErrorDataReceived += (_, args) => OnDataReceived(args.Data);

        if (!process.Start())
          throw new InvalidOperationException($"Failed to start {ldd} process");

        process.BeginOutputReadLine();
        if (shouldFail)
          process.BeginErrorReadLine();

        process.WaitForExit();

        if (process.ExitCode != 0 && (!shouldFail || process.ExitCode != 1))
          throw new InvalidOperationException($"The {ldd} process failed with exit code {process.ExitCode}");
      }
      return builder.ToString();
#endif
    }