Skip to content

Commit dd87588

Browse files
committed
proc: add cwd to process detail view
The process detail panel now shows the working directory above the command line. On Linux this reads the `/proc/[pid]/cwd` symlink, on macOS it uses `proc_pidinfo` with `PROC_PIDVNODEPATHINFO`, and on FreeBSD/NetBSD it uses `sysctl` with `KERN_PROC_CWD`. OpenBSD doesn't expose other processes' cwd so it shows "(unavailable)" there. The CMD display goes from 3 lines to 2 to make room, which means longer commands truncate a line sooner.
1 parent d76e2ca commit dd87588

File tree

7 files changed

+54
-8
lines changed

7 files changed

+54
-8
lines changed

src/btop_draw.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,16 +1848,24 @@ namespace Proc {
18481848
if (item_fit >= 8) out += cjust("Nice:", item_width);
18491849

18501850

1851-
//? Command line
1852-
for (int i = 0; const auto& l : {'C', 'M', 'D'})
1853-
out += Mv::to(d_y + 5 + i++, d_x + 1) + l;
1851+
//? CWD and Command line
1852+
out += Mv::to(d_y + 5, d_x + 1) + Theme::c("title") + Fx::b + "CWD" + Fx::ub;
1853+
out += Mv::to(d_y + 6, d_x + 1) + Theme::c("title") + Fx::b + "CMD" + Fx::ub;
1854+
1855+
out += Theme::c("main_fg");
1856+
//? CWD line
1857+
out += Mv::to(d_y + 5, d_x + 5);
1858+
if (detailed.cwd.empty())
1859+
out += Theme::c("inactive_fg") + "(unavailable)";
1860+
else
1861+
out += uresize(detailed.cwd, d_width - 6, true);
18541862

1855-
out += Theme::c("main_fg") + Fx::ub;
1863+
//? Command lines (2 lines)
18561864
const auto san_cmd = replace_ascii_control(detailed.entry.cmd);
18571865
const int cmd_size = ulen(san_cmd, true);
1858-
for (int num_lines = min(3, (int)ceil((double)cmd_size / (d_width - 5))), i = 0; i < num_lines; i++) {
1859-
out += Mv::to(d_y + 5 + (num_lines == 1 ? 1 : i), d_x + 3)
1860-
+ cjust(luresize(san_cmd, cmd_size - (d_width - 5) * i, true), d_width - 5, true, true);
1866+
for (int num_lines = min(2, (int)ceil((double)cmd_size / (d_width - 6))), i = 0; i < num_lines; i++) {
1867+
out += Mv::to(d_y + 6 + (num_lines == 1 ? 0 : i), d_x + 5)
1868+
+ cjust(luresize(san_cmd, cmd_size - (d_width - 6) * i, true), d_width - 6, true, true);
18611869
}
18621870

18631871
}

src/btop_shared.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ namespace Proc {
422422
size_t last_pid{};
423423
bool skip_smaps{};
424424
proc_info entry;
425-
string elapsed, parent, status, io_read, io_write, memory;
425+
string elapsed, parent, status, io_read, io_write, memory, cwd;
426426
long long first_mem = -1;
427427
deque<long long> cpu_percent;
428428
deque<long long> mem_bytes;

src/freebsd/btop_collect.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,16 @@ namespace Proc {
10741074
// detailed.io_read = floating_humanizer(rusage.ri_diskio_bytesread);
10751075
// detailed.io_write = floating_humanizer(rusage.ri_diskio_byteswritten);
10761076
// }
1077+
1078+
//? Get current working directory via sysctl
1079+
detailed.cwd.clear();
1080+
{
1081+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_CWD, (int)pid};
1082+
char cwdbuf[PATH_MAX];
1083+
size_t cwdlen = sizeof(cwdbuf);
1084+
if (sysctl(mib, 4, cwdbuf, &cwdlen, nullptr, 0) == 0)
1085+
detailed.cwd = cwdbuf;
1086+
}
10771087
}
10781088

10791089
//* Collects and sorts process information from /proc

src/linux/btop_collect.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2909,6 +2909,14 @@ namespace Proc {
29092909
catch (const std::out_of_range&) {}
29102910
d_read.close();
29112911
}
2912+
2913+
//? Get current working directory from proc/[pid]/cwd symlink
2914+
detailed.cwd.clear();
2915+
try {
2916+
if (fs::is_symlink(pid_path / "cwd"))
2917+
detailed.cwd = fs::read_symlink(pid_path / "cwd").string();
2918+
}
2919+
catch (...) {}
29122920
}
29132921

29142922
//* Collects and sorts process information from /proc

src/netbsd/btop_collect.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,16 @@ namespace Proc {
11601160
}
11611161

11621162
while (cmp_greater(detailed.mem_bytes.size(), width)) detailed.mem_bytes.pop_front();
1163+
1164+
//? Get current working directory via sysctl
1165+
detailed.cwd.clear();
1166+
{
1167+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_CWD, (int)pid};
1168+
char cwdbuf[PATH_MAX];
1169+
size_t cwdlen = sizeof(cwdbuf);
1170+
if (sysctl(mib, 4, cwdbuf, &cwdlen, nullptr, 0) == 0)
1171+
detailed.cwd = cwdbuf;
1172+
}
11631173
}
11641174

11651175
//* Collects and sorts process information from /proc

src/openbsd/btop_collect.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,9 @@ namespace Proc {
10251025
}
10261026

10271027
while (cmp_greater(detailed.mem_bytes.size(), width)) detailed.mem_bytes.pop_front();
1028+
1029+
//? OpenBSD doesn't expose other processes' cwd
1030+
detailed.cwd.clear();
10281031
}
10291032

10301033
//* Collects and sorts process information from /proc

src/osx/btop_collect.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,13 @@ namespace Proc {
16571657
detailed.io_read = floating_humanizer(rusage.ri_diskio_bytesread);
16581658
detailed.io_write = floating_humanizer(rusage.ri_diskio_byteswritten);
16591659
}
1660+
1661+
//? Get current working directory
1662+
detailed.cwd.clear();
1663+
struct proc_vnodepathinfo vpi;
1664+
if (proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)) > 0) {
1665+
detailed.cwd = vpi.pvi_cdir.vip_path;
1666+
}
16601667
}
16611668

16621669
//* Collects and sorts process information from /proc

0 commit comments

Comments
 (0)