module patch.rightclicktoplumb; import core.sys.posix.unistd : fork, chdir, execvp, pid_t, _exit; import core.sys.posix.sys.wait : waitpid; import core.stdc.stdio : snprintf; import core.stdc.stdlib : exit; import std.string : toStringz; import patches : isPatchEnabled; import st : pid; enum PATH_MAX = 4096; // Define plumb_cmd enum plumb_cmd = "plumb"; static if (isPatchEnabled!"RIGHTCLICKTOPLUMB_PATCH") { version(linux) { int subprocwd(char* path) { if (snprintf(path, PATH_MAX, "/proc/%d/cwd", pid) < 0) return -1; return 0; } } else version(OpenBSD) { import core.sys.openbsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC_CWD; int subprocwd(char* path) { size_t sz = PATH_MAX; int[3] name = [CTL_KERN, KERN_PROC_CWD, pid]; if (sysctl(name.ptr, 3, path, &sz, null, 0) == -1) return -1; return 0; } } else { int subprocwd(char* path) { return -1; } } void plumb(char* sel) { if (sel == null) return; char[PATH_MAX] cwd; pid_t child; if (subprocwd(cwd.ptr) != 0) return; switch(child = fork()) { case -1: return; case 0: if (chdir(cwd.ptr) != 0) exit(1); char*[3] argv = [cast(char*)plumb_cmd.toStringz, sel, null]; if (execvp(plumb_cmd.toStringz, argv.ptr) == -1) exit(1); exit(0); default: waitpid(child, null, 0); } } }