-
Notifications
You must be signed in to change notification settings - Fork 1
/
mod.ts
122 lines (98 loc) · 2.44 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
interface KillPortOptions {
protocol: "tcp" | "udp";
}
/**
* Finds and kills the informed port process / task
* @param port Port number
* @param options (optional)
* @return Returns a promise with the port's PID or null if the port PID was not found
*
* Example:
*
* await killPort(8082);
*
*/
export async function killPort(
port: number,
options: KillPortOptions = {
protocol: "tcp",
},
): Promise<number | null> {
return await (Deno.build.os == "windows"
? handleKillPortWindows(port, options)
: handleKillPort(port, options));
}
async function handleKillPortWindows(
port: number,
options: KillPortOptions,
): Promise<number | null> {
const pid = await getPidPortWindows(port, options);
if (!pid) {
return null;
}
await killProcessWindows(pid);
return pid;
}
async function getPidPortWindows(
port: number,
options: KillPortOptions,
): Promise<number | null> {
const cmd = Deno.run({
cmd: ["cmd", "/c", "netstat -a -n -o | findstr", `${port}`],
stdout: "piped",
stderr: "piped",
});
const output = new TextDecoder("utf-8").decode(await cmd.output());
const lines = output.split("\n");
const lineWithLocalPortRegEx = new RegExp(
`^ *${options.protocol.toUpperCase()} *[^ ]*:${port}`,
"gm",
);
const linesWithLocalPort = lines.filter((line) =>
line.match(lineWithLocalPortRegEx)
);
const pid = linesWithLocalPort[0].trim().split(/[\s, ]+/)[3];
return pid ? parseInt(pid) : null;
}
async function killProcessWindows(pid: number): Promise<void> {
const cmd = Deno.run({
cmd: ["cmd", "/c", `taskkill /PID ${pid} /F`],
stdout: "piped",
stderr: "piped",
});
await cmd.output();
cmd.close();
}
async function handleKillPort(
port: number,
options: KillPortOptions,
): Promise<number | null> {
const pid = await getPidPort(port, options);
if (!pid) {
return null;
}
await killProcess(pid);
return pid;
}
async function getPidPort(
port: number,
options: KillPortOptions,
): Promise<number> {
const cmd = Deno.run({
cmd: ["fuser", `${port}/${options.protocol}`],
stdout: "piped",
stderr: "piped",
});
const output = await cmd.output();
cmd.close();
return parseInt((new TextDecoder().decode(output)).trim());
}
async function killProcess(pid: number): Promise<void> {
const cmd = Deno.run({
cmd: ["kill", "-9", `${pid}`],
stdout: "piped",
stderr: "piped",
});
await cmd.output();
cmd.close();
}