Use ProcessStartInfo.EnvironmentVariables instead of shell to run Tor on Linux & macOS.
MODIFY
WalletWasabi/Tor/TorProcessManager.cs
WalletWasabi/Tor/TorProcessManager.cs
@@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Helpers;
using WalletWasabi.Logging;
+using WalletWasabi.Microservices;
using WalletWasabi.Tor.Exceptions;
using WalletWasabi.Tor.Http;
using WalletWasabi.Tor.Socks5;
@@ -52,7 +53,7 @@ namespace WalletWasabi.Tor
public static bool RequestFallbackAddressUsage { get; private set; } = false;
- private Process? TorProcess { get; set; }
+ private ProcessAsync? TorProcess { get; set; }
private TorSettings Settings { get; }
@@ -113,25 +114,32 @@ namespace WalletWasabi.Tor
torArguments += $" --Log \"notice file {logFileFullPath}\"";
}
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- TorProcess = Process.Start(new ProcessStartInfo
+ var startInfo = new ProcessStartInfo
{
FileName = Settings.TorPath,
Arguments = torArguments,
UseShellExecute = false,
CreateNoWindow = true,
- RedirectStandardOutput = true
- });
- Logger.LogInfo($"Starting Tor process with Process.Start.");
- }
- else // Linux and OSX
+ RedirectStandardOutput = true,
+ WorkingDirectory = Settings.TorDir
+ };
+
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- string runTorCmd = $"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:='{Settings.TorDir}/Tor' && export LD_LIBRARY_PATH && cd '{Settings.TorDir}/Tor' && ./tor {torArguments}";
- EnvironmentHelpers.ShellExecAsync(runTorCmd, waitForExit: false).GetAwaiter().GetResult();
- Logger.LogInfo($"Started Tor process with shell command: {runTorCmd}.");
+ var env = startInfo.EnvironmentVariables;
+
+ env["LD_LIBRARY_PATH"] = !env.ContainsKey("LD_LIBRARY_PATH") || string.IsNullOrEmpty(env["LD_LIBRARY_PATH"])
+ ? Settings.TorBinaryDir
+ : Settings.TorBinaryDir + Path.PathSeparator + env["LD_LIBRARY_PATH"];
+
+ Logger.LogDebug($"Environment variable 'LD_LIBRARY_PATH' set to: '{env["LD_LIBRARY_PATH"]}'.");
}
+ TorProcess = new ProcessAsync(startInfo);
+
+ Logger.LogInfo($"Starting Tor process ...");
+ TorProcess.Start();
+
if (ensureRunning)
{
Task.Delay(3000).ConfigureAwait(false).GetAwaiter().GetResult(); // dotnet brainfart, ConfigureAwait(false) IS NEEDED HERE otherwise (only on) Manjuro Linux fails, WTF?!!

MODIFY
WalletWasabi/Tor/TorSettings.cs
WalletWasabi/Tor/TorSettings.cs
@@ -17,30 +17,35 @@ namespace WalletWasabi.Tor
public TorSettings(string dataDir, string logFilePath)
{
TorDir = Path.Combine(dataDir, "tor");
+ TorBinaryDir = Path.Combine(TorDir, "Tor");
TorDataDir = Path.Combine(dataDir, "tordata");
LogFilePath = logFilePath;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- TorPath = $@"{TorDir}\Tor\tor.exe";
- HashSourcePath = $@"{TorDir}\Tor\tor.exe";
+ TorPath = $@"{TorBinaryDir}\tor.exe";
+ HashSourcePath = $@"{TorBinaryDir}\tor.exe";
GeoIpPath = $@"{TorDir}\Data\Tor\geoip";
GeoIp6Path = $@"{TorDir}\Data\Tor\geoip6";
}
else
{
- TorPath = $@"{TorDir}/Tor/tor";
+ TorPath = $@"{TorBinaryDir}/tor";
HashSourcePath = RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
- ? $@"{TorDir}/Tor/tor.real"
- : $@"{TorDir}/Tor/tor";
+ ? $@"{TorBinaryDir}/tor.real"
+ : $@"{TorBinaryDir}/tor";
GeoIpPath = $@"{TorDir}/Data/Tor/geoip";
GeoIp6Path = $@"{TorDir}/Data/Tor/geoip6";
}
}
/// <summary>Full directory path where Tor is installed (or supposed to be installed).</summary>
+ /// <remarks>Folder contains <c>Data</c> and <c>Tor</c> (see <see cref="TorBinaryDir"/>) sub-folders.</remarks>
public string TorDir { get; }
+ /// <summary>Full directory path where Tor binaries are placed.</summary>
+ public string TorBinaryDir { get; }
+
/// <summary>Full directory path where Tor stores its data.</summary>
public string TorDataDir { get; }

Use ProcessStartInfo.EnvironmentVariables instead of shell to run Tor on Linux & macOS.