Skip to content

Commit 3d23f3e

Browse files
committed
Optimized and improved the code
Optimized and improved the code for killing core processes in non-Windows environments. Now uses a shell script for precise processing.
1 parent 6715d7d commit 3d23f3e

9 files changed

Lines changed: 167 additions & 43 deletions

File tree

v2rayN/ServiceLib/Common/FileManager.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,28 @@ public static void DeleteExpiredFiles(string sourceDir, DateTime dtLine)
223223
// ignored
224224
}
225225
}
226+
227+
/// <summary>
228+
/// Creates a Linux shell file with the specified contents.
229+
/// </summary>
230+
/// <param name="fileName"></param>
231+
/// <param name="contents"></param>
232+
/// <param name="overwrite"></param>
233+
/// <returns></returns>
234+
public static async Task<string> CreateLinuxShellFile(string fileName, string contents, bool overwrite)
235+
{
236+
var shFilePath = Utils.GetBinConfigPath(fileName);
237+
238+
// Check if the file already exists and if we should overwrite it
239+
if (!overwrite && File.Exists(shFilePath))
240+
{
241+
return shFilePath;
242+
}
243+
244+
File.Delete(shFilePath);
245+
await File.WriteAllTextAsync(shFilePath, contents);
246+
await Utils.SetLinuxChmod(shFilePath);
247+
248+
return shFilePath;
249+
}
226250
}

v2rayN/ServiceLib/Global.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public class Global
3838
public const string PacFileName = NamespaceSample + "pac";
3939
public const string ProxySetOSXShellFileName = NamespaceSample + "proxy_set_osx_sh";
4040
public const string ProxySetLinuxShellFileName = NamespaceSample + "proxy_set_linux_sh";
41+
public const string KillAsSudoOSXShellFileName = NamespaceSample + "kill_as_sudo_osx_sh";
42+
public const string KillAsSudoLinuxShellFileName = NamespaceSample + "kill_as_sudo_linux_sh";
4143

4244
public const string DefaultSecurity = "auto";
4345
public const string DefaultNetwork = "tcp";

v2rayN/ServiceLib/Handler/CoreAdminHandler.cs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Diagnostics;
22
using System.Text;
33
using CliWrap;
4+
using CliWrap.Buffered;
45

56
namespace ServiceLib.Handler;
67

@@ -11,6 +12,7 @@ public class CoreAdminHandler
1112
private Config _config;
1213
private Action<bool, string>? _updateFunc;
1314
private int _linuxSudoPid = -1;
15+
private const string _tag = "CoreAdminHandler";
1416

1517
public async Task Init(Config config, Action<bool, string> updateFunc)
1618
{
@@ -31,8 +33,11 @@ private void UpdateFunc(bool notify, string msg)
3133

3234
public async Task<Process?> RunProcessAsLinuxSudo(string fileName, CoreInfo coreInfo, string configPath)
3335
{
36+
StringBuilder sb = new();
37+
sb.AppendLine("#!/bin/bash");
3438
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
35-
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
39+
sb.AppendLine($"sudo -S {cmdLine}");
40+
var shFilePath = await FileManager.CreateLinuxShellFile("run_as_sudo.sh", sb.ToString(), true);
3641

3742
Process proc = new()
3843
{
@@ -87,35 +92,24 @@ public async Task KillProcessAsLinuxSudo()
8792
return;
8893
}
8994

90-
var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
91-
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
95+
try
96+
{
97+
var shellFileName = Utils.IsOSX() ? Global.KillAsSudoOSXShellFileName : Global.KillAsSudoLinuxShellFileName;
98+
var shFilePath = await FileManager.CreateLinuxShellFile("kill_as_sudo.sh", EmbedUtils.GetEmbedText(shellFileName), true);
9299

93-
await Cli.Wrap(shFilePath)
94-
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
95-
.ExecuteAsync();
100+
var arg = new List<string>() { "-c", $"sudo -S {shFilePath} {_linuxSudoPid}" };
101+
var result = await Cli.Wrap(Global.LinuxBash)
102+
.WithArguments(arg)
103+
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
104+
.ExecuteBufferedAsync();
96105

97-
_linuxSudoPid = -1;
98-
}
99-
100-
private async Task<string> CreateLinuxShellFile(string cmdLine, string fileName)
101-
{
102-
var shFilePath = Utils.GetBinConfigPath(fileName);
103-
File.Delete(shFilePath);
104-
105-
var sb = new StringBuilder();
106-
sb.AppendLine("#!/bin/sh");
107-
if (Utils.IsAdministrator())
108-
{
109-
sb.AppendLine($"{cmdLine}");
106+
UpdateFunc(false, result.StandardOutput.ToString());
110107
}
111-
else
108+
catch (Exception ex)
112109
{
113-
sb.AppendLine($"sudo -S {cmdLine}");
110+
Logging.SaveLog(_tag, ex);
114111
}
115112

116-
await File.WriteAllTextAsync(shFilePath, sb.ToString());
117-
await Utils.SetLinuxChmod(shFilePath);
118-
119-
return shFilePath;
113+
_linuxSudoPid = -1;
120114
}
121115
}

v2rayN/ServiceLib/Handler/SysProxy/ProxySettingLinux.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,7 @@ public static async Task UnsetProxy()
1818

1919
private static async Task ExecCmd(List<string> args)
2020
{
21-
var fileName = Utils.GetBinConfigPath(_proxySetFileName);
22-
if (!File.Exists(fileName))
23-
{
24-
var contents = EmbedUtils.GetEmbedText(Global.ProxySetLinuxShellFileName);
25-
await File.AppendAllTextAsync(fileName, contents);
26-
27-
await Utils.SetLinuxChmod(fileName);
28-
}
21+
var fileName = await FileManager.CreateLinuxShellFile(_proxySetFileName, EmbedUtils.GetEmbedText(Global.ProxySetLinuxShellFileName), false);
2922

3023
await Utils.GetCliWrapOutput(fileName, args);
3124
}

v2rayN/ServiceLib/Handler/SysProxy/ProxySettingOSX.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,7 @@ public static async Task UnsetProxy()
2323

2424
private static async Task ExecCmd(List<string> args)
2525
{
26-
var fileName = Utils.GetBinConfigPath(_proxySetFileName);
27-
if (!File.Exists(fileName))
28-
{
29-
var contents = EmbedUtils.GetEmbedText(Global.ProxySetOSXShellFileName);
30-
await File.AppendAllTextAsync(fileName, contents);
31-
32-
await Utils.SetLinuxChmod(fileName);
33-
}
26+
var fileName = await FileManager.CreateLinuxShellFile(_proxySetFileName, EmbedUtils.GetEmbedText(Global.ProxySetOSXShellFileName), false);
3427

3528
await Utils.GetCliWrapOutput(fileName, args);
3629
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
#
3+
# Process Terminator Script for Linux
4+
# This script forcibly terminates a process and all its child processes
5+
#
6+
7+
# Check if PID argument is provided
8+
if [ $# -ne 1 ]; then
9+
echo "Usage: $0 <PID>"
10+
exit 1
11+
fi
12+
13+
PID=$1
14+
15+
# Validate that input is a valid PID (numeric)
16+
if ! [[ "$PID" =~ ^[0-9]+$ ]]; then
17+
echo "Error: The PID must be a numeric value"
18+
exit 1
19+
fi
20+
21+
# Check if the process exists
22+
if ! ps -p $PID > /dev/null; then
23+
echo "Warning: No process found with PID $PID"
24+
exit 0
25+
fi
26+
27+
# Recursive function to find and kill all child processes
28+
kill_children() {
29+
local parent=$1
30+
local children=$(ps -o pid --no-headers --ppid "$parent")
31+
32+
# Output information about processes being terminated
33+
echo "Processing children of PID: $parent..."
34+
35+
# Process each child
36+
for child in $children; do
37+
# Recursively find and kill child's children first
38+
kill_children "$child"
39+
40+
# Force kill the child process
41+
echo "Terminating child process: $child"
42+
kill -9 "$child" 2>/dev/null || true
43+
done
44+
}
45+
46+
echo "============================================"
47+
echo "Starting termination of process $PID and all its children"
48+
echo "============================================"
49+
50+
# Find and kill all child processes
51+
kill_children "$PID"
52+
53+
# Finally kill the main process
54+
echo "Terminating main process: $PID"
55+
kill -9 "$PID" 2>/dev/null || true
56+
57+
echo "============================================"
58+
echo "Process $PID and all its children have been terminated"
59+
echo "============================================"
60+
61+
exit 0
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/bash
2+
#
3+
# Process Terminator Script for macOS
4+
# This script forcibly terminates a process and all its descendant processes
5+
#
6+
7+
# Check if PID argument is provided
8+
if [ $# -ne 1 ]; then
9+
echo "Usage: $0 <PID>"
10+
exit 1
11+
fi
12+
13+
PID=$1
14+
15+
# Validate that input is a valid PID (numeric)
16+
if ! [[ "$PID" =~ ^[0-9]+$ ]]; then
17+
echo "Error: The PID must be a numeric value"
18+
exit 1
19+
fi
20+
21+
# Check if the process exists
22+
if ! ps -p $PID > /dev/null; then
23+
echo "Warning: No process found with PID $PID"
24+
exit 0
25+
fi
26+
27+
# Recursive function to find and kill all descendant processes
28+
kill_descendants() {
29+
local parent=$1
30+
# Use ps -eo pid,ppid for macOS compatibility
31+
local children=$(ps -eo pid=,ppid= | awk -v ppid=$parent '$2==ppid {print $1}')
32+
33+
echo "Processing children of PID: $parent..."
34+
for child in $children; do
35+
kill_descendants "$child"
36+
echo "Terminating child process: $child"
37+
kill -9 "$child" 2>/dev/null || true
38+
done
39+
}
40+
41+
echo "============================================"
42+
echo "Starting termination of process $PID and all its descendants"
43+
echo "============================================"
44+
45+
# Find and kill all descendant processes
46+
kill_descendants "$PID"
47+
48+
# Finally kill the main process
49+
echo "Terminating main process: $PID"
50+
kill -9 "$PID" 2>/dev/null || true
51+
52+
echo "============================================"
53+
echo "Process $PID and all its descendants have been terminated"
54+
echo "============================================"
55+
56+
exit 0

v2rayN/ServiceLib/ServiceLib.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
<EmbeddedResource Include="Sample\custom_routing_white" />
2929
<EmbeddedResource Include="Sample\dns_singbox_normal" />
3030
<EmbeddedResource Include="Sample\dns_v2ray_normal" />
31+
<EmbeddedResource Include="Sample\kill_as_sudo_linux_sh" />
32+
<EmbeddedResource Include="Sample\kill_as_sudo_osx_sh" />
3133
<EmbeddedResource Include="Sample\pac" />
3234
<EmbeddedResource Include="Sample\proxy_set_linux_sh" />
3335
<EmbeddedResource Include="Sample\proxy_set_osx_sh" />

v2rayN/v2rayN.Desktop/Views/SudoPasswordInputView.axaml.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ private async Task<bool> CheckSudoPasswordAsync(string password)
6666
{
6767
// Use sudo echo command to verify password
6868
var arg = new List<string>() { "-c", "sudo -S echo SUDO_CHECK" };
69-
var result = await CliWrap.Cli
70-
.Wrap(Global.LinuxBash)
69+
var result = await CliWrap.Cli.Wrap(Global.LinuxBash)
7170
.WithArguments(arg)
7271
.WithStandardInputPipe(CliWrap.PipeSource.FromString(password))
7372
.ExecuteBufferedAsync();

0 commit comments

Comments
 (0)