62 lines
1.6 KiB
D
62 lines
1.6 KiB
D
|
|
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|