whoisport 0.0.0-stage → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kaitlyn Bassford
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,116 @@
1
- # Temporary Holding Version
1
+ # whoisport
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![crates.io](https://img.shields.io/crates/v/whoisport.svg)](https://crates.io/crates/whoisport)
4
+ [![CI](https://github.com/dpologdvinity/whoisport/actions/workflows/ci.yml/badge.svg)](https://github.com/dpologdvinity/whoisport/actions/workflows/ci.yml)
5
+
6
+ Find out what is listening on a TCP or UDP port, and optionally kill it.
7
+
8
+ ![whoisport demo](demo.gif)
9
+
10
+ ```console
11
+ $ whoisport 3000
12
+ port 3000
13
+ pid 373232
14
+ parent 373230
15
+ user kaitlyn
16
+ cmd node node_modules/.bin/vite --port 3000
17
+ cwd /home/kaitlyn/site
18
+ uptime 4m 12s
19
+
20
+ $ whoisport 3000 --kill
21
+ ...
22
+ pid 373232: exited after SIGTERM
23
+
24
+ $ whoisport
25
+ PORT PID USER CMD
26
+ 3000 373232 kaitlyn node node_modules/.bin/vite --port 3000
27
+ 5432 ? ? ?
28
+ 8080 41120 kaitlyn python3 -m http.server 8080
29
+ ports marked ? are owned by another user; run with sudo to see it
30
+ ```
31
+
32
+ `lsof -i :3000` gives you a PID and a wall of columns. `whoisport` gives you the
33
+ command line, the directory it was started from, who owns it and how long it has
34
+ been running, which is usually what you need to decide whether to kill it.
35
+
36
+ ## Install
37
+
38
+ ```sh
39
+ cargo binstall whoisport # prebuilt binary, no compiling
40
+ cargo install whoisport # build from source
41
+ pipx install whoisport # or: uvx whoisport, pip install whoisport
42
+ ```
43
+
44
+ macOS or Linux, with [Homebrew](https://brew.sh):
45
+
46
+ ```sh
47
+ brew install dpologdvinity/tap/whoisport
48
+ ```
49
+
50
+ Debian/Ubuntu or Fedora/RHEL: download the `.deb` or `.rpm` for your architecture
51
+ from the [Releases page](https://github.com/dpologdvinity/whoisport/releases), then
52
+
53
+ ```sh
54
+ sudo apt install ./whoisport_*.deb # Debian, Ubuntu
55
+ sudo dnf install ./whoisport-*.rpm # Fedora, RHEL
56
+ ```
57
+
58
+ Windows, with [Scoop](https://scoop.sh):
59
+
60
+ ```powershell
61
+ scoop bucket add whoisport https://github.com/dpologdvinity/whoisport
62
+ scoop install whoisport
63
+ ```
64
+
65
+ Or download a binary from the
66
+ [Releases page](https://github.com/dpologdvinity/whoisport/releases): Linux (static,
67
+ x86_64 and aarch64), macOS (Apple Silicon and Intel) and Windows (x86_64).
68
+
69
+ Works on **Linux** (reads `/proc` directly, no runtime dependencies), **macOS**
70
+ (uses the built-in `lsof`) and **Windows 10/11**.
71
+
72
+ ## Usage
73
+
74
+ ```
75
+ whoisport # list every listening port
76
+ whoisport <PORT>... # details for one or more ports
77
+ whoisport <PORT>... --kill [--force]
78
+ whoisport [<PORT>...] --json # machine-readable output
79
+ whoisport [<PORT>...] --udp # UDP instead of TCP
80
+ ```
81
+
82
+ | Flag | Effect |
83
+ |-----------|---------------------------------------------------------------------|
84
+ | `--kill` | Ask the process to exit and wait up to 3 seconds. |
85
+ | `--force` | With `--kill`: forcibly terminate it if asking did not work. |
86
+ | `--json` | Print a JSON array with `port`, `proto`, `pid`, `ppid`, `user`, `cmd`, `cwd`, `uptime_secs`, `container`, `image`. |
87
+ | `--udp` | Look at UDP sockets instead of TCP. UDP has no listening state, so any bound socket without a remote peer counts. Windows doesn't report UDP peers, so there every bound UDP socket is listed, including short-lived client ones. |
88
+
89
+ Docker: when a port is published by a container, whoisport shows the container
90
+ name and image (`docker web (nginx:alpine)`), even when the `docker-proxy`
91
+ process itself is owned by root. It asks `docker ps` only in that case.
92
+
93
+ `--kill` always needs explicit ports; it never kills everything.
94
+
95
+ How `--kill` asks, per platform:
96
+
97
+ | Platform | `--kill` | `--force` |
98
+ |----------|-----------------------------------------------------------------|--------------------|
99
+ | Linux, macOS | `SIGTERM` | `SIGKILL` |
100
+ | Windows | Ctrl+C in the process's console, and `WM_CLOSE` to its windows | `TerminateProcess` |
101
+
102
+ On Windows, Ctrl+C reaches every program attached to a console, so whoisport only
103
+ sends it when the target's console holds nothing but the target, its child
104
+ processes and a shell. Otherwise it says so and leaves the choice of `--force` to you.
105
+
106
+ Exit codes: `0` success, `1` a requested port had nothing listening (or nothing
107
+ is listening at all), `2` invalid arguments, `3` a kill failed.
108
+
109
+ Checks IPv4 and IPv6 TCP sockets in the LISTEN state. On Linux, processes owned
110
+ by other users can't be inspected without `sudo`; they show up as `?`. On
111
+ Windows, details of system services need an elevated terminal. On macOS,
112
+ other users' listeners only appear when run with `sudo`.
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ // Runs the prebuilt whoisport binary from the platform package that npm (or pnpm,
4
+ // yarn, bun) installed as an optional dependency.
5
+ const { spawnSync } = require("node:child_process");
6
+
7
+ const packages = {
8
+ "linux x64": "whoisport-linux-x64",
9
+ "linux arm64": "whoisport-linux-arm64",
10
+ "darwin x64": "whoisport-darwin-x64",
11
+ "darwin arm64": "whoisport-darwin-arm64",
12
+ "win32 x64": "whoisport-win32-x64",
13
+ };
14
+ const name = packages[`${process.platform} ${process.arch}`];
15
+ if (!name) {
16
+ console.error(`whoisport: no prebuilt binary for ${process.platform}-${process.arch}`);
17
+ process.exit(1);
18
+ }
19
+ const exe = process.platform === "win32" ? "whoisport.exe" : "whoisport";
20
+ let bin;
21
+ try {
22
+ bin = require.resolve(`${name}/bin/${exe}`);
23
+ } catch {
24
+ console.error(`whoisport: ${name} is not installed (optional dependencies skipped?)`);
25
+ process.exit(1);
26
+ }
27
+ const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
28
+ if (result.error) {
29
+ console.error(`whoisport: ${result.error.message}`);
30
+ process.exit(1);
31
+ }
32
+ if (result.signal) process.kill(process.pid, result.signal);
33
+ process.exit(result.status ?? 1);
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "whoisport",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "Show what is listening on a TCP or UDP port, and optionally kill it",
4
+ "version": "0.5.2",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/dpologdvinity/whoisport.git"
9
+ },
10
+ "homepage": "https://github.com/dpologdvinity/whoisport",
11
+ "keywords": [
12
+ "port",
13
+ "process",
14
+ "cli",
15
+ "lsof",
16
+ "devtools",
17
+ "kill-port"
18
+ ],
19
+ "bin": {
20
+ "whoisport": "bin/whoisport.js"
21
+ },
22
+ "files": [
23
+ "bin/",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "engines": {
28
+ "node": ">=16"
29
+ },
30
+ "optionalDependencies": {
31
+ "whoisport-linux-x64": "0.5.2",
32
+ "whoisport-linux-arm64": "0.5.2",
33
+ "whoisport-darwin-x64": "0.5.2",
34
+ "whoisport-darwin-arm64": "0.5.2",
35
+ "whoisport-win32-x64": "0.5.2"
36
+ }
37
+ }