Skip to content

Commit 0412124

Browse files
authored
Merge pull request #38 from jacobtread-contrib/fix-windows-builds
fix: update windows for new changes
2 parents 4997258 + 64d2e5a commit 0412124

File tree

16 files changed

+617
-200
lines changed

16 files changed

+617
-200
lines changed

.github/workflows/build.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
- s390x-unknown-linux-gnu
2020
- aarch64-apple-darwin
2121
- x86_64-apple-darwin
22+
- x86_64-pc-windows-gnu
2223
runs-on: ${{ (matrix.target == 'aarch64-apple-darwin' || matrix.target == 'x86_64-apple-darwin') && 'macos-latest' || 'ubuntu-latest' }}
2324
steps:
2425
- name: Checkout repository

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
- s390x-unknown-linux-gnu
6565
- aarch64-apple-darwin
6666
- x86_64-apple-darwin
67-
# - x86_64-pc-windows-gnu
67+
- x86_64-pc-windows-gnu
6868
runs-on: ${{ (matrix.target == 'aarch64-apple-darwin' || matrix.target == 'x86_64-apple-darwin') && 'macos-latest' || 'ubuntu-latest' }}
6969
steps:
7070
- name: Checkout repository

src/cli.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use clap::{Parser, ValueEnum};
22
use clap_verbosity_flag::{Verbosity, WarnLevel};
33
use core::fmt;
4-
use nix::sys::signal::Signal;
5-
use std::str::FromStr;
4+
5+
use crate::signal::KillportSignal;
66

77
/// Modes of operation for killport.
88
#[derive(Debug, Clone, Copy, PartialEq, ValueEnum)]
@@ -67,7 +67,7 @@ pub struct KillPortArgs {
6767
default_value = "sigkill",
6868
value_parser = parse_signal
6969
)]
70-
pub signal: Signal,
70+
pub signal: KillportSignal,
7171

7272
/// A verbosity flag to control the level of logging output.
7373
#[command(flatten)]
@@ -81,14 +81,6 @@ pub struct KillPortArgs {
8181
pub dry_run: bool,
8282
}
8383

84-
fn parse_signal(arg: &str) -> Result<Signal, std::io::Error> {
85-
let str_arg = arg.parse::<String>();
86-
match str_arg {
87-
Ok(str_arg) => {
88-
let signal_str = str_arg.to_uppercase();
89-
let signal = Signal::from_str(signal_str.as_str())?;
90-
return Ok(signal);
91-
}
92-
Err(e) => Err(std::io::Error::new(std::io::ErrorKind::Other, e)),
93-
}
84+
fn parse_signal(arg: &str) -> Result<KillportSignal, std::io::Error> {
85+
arg.to_uppercase().parse()
9486
}

src/docker.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
use crate::signal::KillportSignal;
12
use bollard::container::{KillContainerOptions, ListContainersOptions};
23
use bollard::Docker;
34
use log::debug;
4-
use nix::sys::signal::Signal;
55
use std::collections::HashMap;
66
use std::io::Error;
77
use tokio::runtime::Runtime;
@@ -17,7 +17,7 @@ impl DockerContainer {
1717
///
1818
/// * `name` - A container name.
1919
/// * `signal` - A enum value representing the signal type.
20-
pub fn kill_container(name: &String, signal: Signal) -> Result<(), Error> {
20+
pub fn kill_container(name: &str, signal: KillportSignal) -> Result<(), Error> {
2121
let rt = Runtime::new()?;
2222
rt.block_on(async {
2323
let docker = Docker::connect_with_socket_defaults()
@@ -63,11 +63,7 @@ impl DockerContainer {
6363
.as_ref()?
6464
.first()
6565
.map(|name| DockerContainer {
66-
name: if name.starts_with('/') {
67-
name[1..].to_string()
68-
} else {
69-
name.clone()
70-
},
66+
name: name.strip_prefix('/').unwrap_or(name).to_string(),
7167
})
7268
})
7369
.collect())

src/killport.rs

Lines changed: 31 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,34 @@
1-
use crate::cli::Mode;
21
use crate::docker::DockerContainer;
32
#[cfg(target_os = "linux")]
43
use crate::linux::find_target_processes;
54
#[cfg(target_os = "macos")]
65
use crate::macos::find_target_processes;
7-
use log::info;
8-
use nix::sys::signal::{kill, Signal};
9-
use nix::unistd::Pid;
10-
use std::io::Error;
11-
12-
#[derive(Debug)]
13-
pub struct NativeProcess {
14-
/// System native process ID.
15-
pub pid: Pid,
16-
pub name: String,
17-
}
6+
#[cfg(target_os = "windows")]
7+
use crate::windows::find_target_processes;
8+
use crate::{cli::Mode, signal::KillportSignal};
9+
use std::{fmt::Display, io::Error};
1810

1911
/// Interface for killable targets such as native process and docker container.
2012
pub trait Killable {
21-
fn kill(&self, signal: Signal) -> Result<bool, Error>;
22-
fn get_type(&self) -> String;
13+
fn kill(&self, signal: KillportSignal) -> Result<bool, Error>;
14+
15+
fn get_type(&self) -> KillableType;
16+
2317
fn get_name(&self) -> String;
2418
}
2519

26-
impl Killable for NativeProcess {
27-
/// Entry point to kill the linux native process.
28-
///
29-
/// # Arguments
30-
///
31-
/// * `signal` - A enum value representing the signal type.
32-
fn kill(&self, signal: Signal) -> Result<bool, Error> {
33-
info!("Killing process '{}' with PID {}", self.name, self.pid);
34-
35-
kill(self.pid, signal).map(|_| true).map_err(|e| {
36-
Error::new(
37-
std::io::ErrorKind::Other,
38-
format!(
39-
"Failed to kill process '{}' with PID {}: {}",
40-
self.name, self.pid, e
41-
),
42-
)
43-
})
44-
}
45-
46-
/// Returns the type of the killable target.
47-
///
48-
/// This method is used to identify the type of the target (either a native process or a Docker container)
49-
/// that is being handled. This information can be useful for logging, error handling, or other needs
50-
/// where type of the target is relevant.
51-
///
52-
/// # Returns
53-
///
54-
/// * `String` - A string that describes the type of the killable target. For a `NativeProcess` it will return "process",
55-
/// and for a `DockerContainer` it will return "container".
56-
fn get_type(&self) -> String {
57-
"process".to_string()
58-
}
20+
#[derive(Debug, Clone, PartialEq, Eq)]
21+
pub enum KillableType {
22+
Process,
23+
Container,
24+
}
5925

60-
fn get_name(&self) -> String {
61-
self.name.to_string()
26+
impl Display for KillableType {
27+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28+
f.write_str(match self {
29+
KillableType::Process => "process",
30+
KillableType::Container => "container",
31+
})
6232
}
6333
}
6434

@@ -68,10 +38,8 @@ impl Killable for DockerContainer {
6838
/// # Arguments
6939
///
7040
/// * `signal` - A enum value representing the signal type.
71-
fn kill(&self, signal: Signal) -> Result<bool, Error> {
72-
if let Err(err) = Self::kill_container(&self.name, signal) {
73-
return Err(err);
74-
}
41+
fn kill(&self, signal: KillportSignal) -> Result<bool, Error> {
42+
Self::kill_container(&self.name, signal)?;
7543

7644
Ok(true)
7745
}
@@ -84,10 +52,10 @@ impl Killable for DockerContainer {
8452
///
8553
/// # Returns
8654
///
87-
/// * `String` - A string that describes the type of the killable target. For a `NativeProcess` it will return "process",
55+
/// * `String` - A string that describes the type of the killable target. For a `UnixProcess` it will return "process",
8856
/// and for a `DockerContainer` it will return "container".
89-
fn get_type(&self) -> String {
90-
"container".to_string()
57+
fn get_type(&self) -> KillableType {
58+
KillableType::Container
9159
}
9260

9361
fn get_name(&self) -> String {
@@ -104,10 +72,10 @@ pub trait KillportOperations {
10472
fn kill_service_by_port(
10573
&self,
10674
port: u16,
107-
signal: Signal,
75+
signal: KillportSignal,
10876
mode: Mode,
10977
dry_run: bool,
110-
) -> Result<Vec<(String, String)>, Error>;
78+
) -> Result<Vec<(KillableType, String)>, Error>;
11179
}
11280

11381
pub struct Killport;
@@ -133,9 +101,10 @@ impl KillportOperations for Killport {
133101

134102
for process in target_processes {
135103
// Check if the process name contains 'docker' and skip if in docker mode
136-
if docker_present && process.name.to_lowercase().contains("docker") {
104+
if docker_present && process.get_name().to_lowercase().contains("docker") {
137105
continue;
138106
}
107+
139108
target_killables.push(Box::new(process));
140109
}
141110
}
@@ -166,10 +135,10 @@ impl KillportOperations for Killport {
166135
fn kill_service_by_port(
167136
&self,
168137
port: u16,
169-
signal: Signal,
138+
signal: KillportSignal,
170139
mode: Mode,
171140
dry_run: bool,
172-
) -> Result<Vec<(String, String)>, Error> {
141+
) -> Result<Vec<(KillableType, String)>, Error> {
173142
let mut results = Vec::new();
174143
let target_killables = self.find_target_killables(port, mode)?; // Use the existing function to find targets
175144

@@ -179,7 +148,7 @@ impl KillportOperations for Killport {
179148
results.push((killable.get_type(), killable.get_name()));
180149
} else {
181150
// In actual mode, attempt to kill the entity and collect its information if successful
182-
if killable.kill(signal)? {
151+
if killable.kill(signal.clone())? {
183152
results.push((killable.get_type(), killable.get_name()));
184153
}
185154
}

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
pub mod cli;
22
pub mod docker;
33
pub mod killport;
4+
pub mod signal;
5+
6+
#[cfg(unix)]
7+
pub mod unix;
8+
49
#[cfg(target_os = "linux")]
510
pub mod linux;
611
#[cfg(target_os = "macos")]

src/linux.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::killport::NativeProcess;
1+
use crate::unix::UnixProcess;
22

33
use log::debug;
44
use nix::unistd::Pid;
@@ -75,8 +75,8 @@ fn find_target_inodes(port: u16) -> Vec<u64> {
7575
/// # Arguments
7676
///
7777
/// * `inodes` - Target inodes
78-
pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, Error> {
79-
let mut target_pids: Vec<NativeProcess> = vec![];
78+
pub fn find_target_processes(port: u16) -> Result<Vec<UnixProcess>, Error> {
79+
let mut target_pids: Vec<UnixProcess> = vec![];
8080
let inodes = find_target_inodes(port);
8181

8282
for inode in inodes {
@@ -96,10 +96,7 @@ pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, Error> {
9696
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
9797
.join(" ");
9898
debug!("Found process '{}' with PID {}", name, process.pid());
99-
target_pids.push(NativeProcess {
100-
pid: Pid::from_raw(process.pid),
101-
name: name,
102-
});
99+
target_pids.push(UnixProcess::new(Pid::from_raw(process.pid), name));
103100
}
104101
}
105102
}

src/macos.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::killport::NativeProcess;
1+
use crate::unix::UnixProcess;
22

33
use libproc::libproc::file_info::pidfdinfo;
44
use libproc::libproc::file_info::{ListFDs, ProcFDType};
@@ -16,8 +16,8 @@ use std::io;
1616
/// # Arguments
1717
///
1818
/// * `port` - Target port number
19-
pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, io::Error> {
20-
let mut target_pids: Vec<NativeProcess> = vec![];
19+
pub fn find_target_processes(port: u16) -> Result<Vec<UnixProcess>, io::Error> {
20+
let mut target_pids: Vec<UnixProcess> = vec![];
2121

2222
if let Ok(procs) = pids_by_type(ProcFilter::All) {
2323
for p in procs {
@@ -56,10 +56,10 @@ pub fn find_target_processes(port: u16) -> Result<Vec<NativeProcess>, io::Error>
5656
"Found process '{}' with PID {} listening on port {}",
5757
process_name, pid, port
5858
);
59-
target_pids.push(NativeProcess {
60-
pid: Pid::from_raw(pid),
61-
name: process_name,
62-
});
59+
target_pids.push(UnixProcess::new(
60+
Pid::from_raw(pid),
61+
process_name,
62+
));
6363
}
6464
}
6565
_ => (),

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fn main() {
5252

5353
// Attempt to kill processes listening on specified ports
5454
for port in args.ports {
55-
match killport.kill_service_by_port(port, args.signal, args.mode, args.dry_run) {
55+
match killport.kill_service_by_port(port, args.signal.clone(), args.mode, args.dry_run) {
5656
Ok(killed_services) => {
5757
if killed_services.is_empty() {
5858
println!("No {} found using port {}", service_type_singular, port);

src/signal.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//! Wrapper around signals for platforms that they are not supported on
2+
3+
use std::{fmt::Display, str::FromStr};
4+
5+
#[cfg(unix)]
6+
#[derive(Debug, Clone, PartialEq, Eq)]
7+
pub struct KillportSignal(pub nix::sys::signal::Signal);
8+
9+
/// On a platform where we don't have the proper signals enum
10+
#[cfg(not(unix))]
11+
#[derive(Debug, Clone, PartialEq, Eq)]
12+
pub struct KillportSignal(pub String);
13+
14+
impl Display for KillportSignal {
15+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16+
Display::fmt(&self.0, f)
17+
}
18+
}
19+
20+
impl FromStr for KillportSignal {
21+
type Err = std::io::Error;
22+
23+
fn from_str(value: &str) -> Result<Self, Self::Err> {
24+
#[cfg(unix)]
25+
{
26+
let signal = nix::sys::signal::Signal::from_str(value)?;
27+
Ok(KillportSignal(signal))
28+
}
29+
30+
#[cfg(not(unix))]
31+
{
32+
Ok(KillportSignal(value.to_string()))
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)