ww: give captured actions null stdin
This commit is contained in:
@@ -28,13 +28,14 @@ export type result = struct {
|
|||||||
|
|
||||||
// command is deliberately concrete. argv includes argv[0], env is the full
|
// command is deliberately concrete. argv includes argv[0], env is the full
|
||||||
// environment, and an empty dir inherits the caller's working directory.
|
// environment, and an empty dir inherits the caller's working directory.
|
||||||
// stdoutpath and stderrpath are created exclusively with mode 0600. A zero
|
// An empty stdinpath selects the null device; stdoutpath and stderrpath are
|
||||||
// deadline means no timeout.
|
// created exclusively with mode 0600. A zero deadline means no timeout.
|
||||||
export type command = struct {
|
export type command = struct {
|
||||||
path: str,
|
path: str,
|
||||||
argv: []str,
|
argv: []str,
|
||||||
env: []str,
|
env: []str,
|
||||||
dir: str,
|
dir: str,
|
||||||
|
stdinpath: str,
|
||||||
stdoutpath: str,
|
stdoutpath: str,
|
||||||
stderrpath: str,
|
stderrpath: str,
|
||||||
deadline: time.instant,
|
deadline: time.instant,
|
||||||
@@ -124,7 +125,8 @@ fn valid(c: *command) bool = {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if ((c.grace: i64) < 0i64) { return false; };
|
if ((c.grace: i64) < 0i64) { return false; };
|
||||||
if (hasnul(c.path) || hasnul(c.dir) || hasnul(c.stdoutpath)
|
if (hasnul(c.path) || hasnul(c.dir) || hasnul(c.stdinpath)
|
||||||
|
|| hasnul(c.stdoutpath)
|
||||||
|| hasnul(c.stderrpath)) {
|
|| hasnul(c.stderrpath)) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -209,8 +211,8 @@ fn childclose(fd: i32, markerfd: i32) void = {
|
|||||||
if (rc < 0) { childmark(markerfd, rc); };
|
if (rc < 0) { childmark(markerfd, rc); };
|
||||||
};
|
};
|
||||||
|
|
||||||
fn child(c: *command, av: []*u8, ep: []*u8, outfd: i32,
|
fn child(c: *command, av: []*u8, ep: []*u8, infd: i32,
|
||||||
errfd: i32, markerread: i32, markerwrite: i32) void = {
|
outfd: i32, errfd: i32, markerread: i32, markerwrite: i32) void = {
|
||||||
let rc: i32 = os.setpgid(0, 0);
|
let rc: i32 = os.setpgid(0, 0);
|
||||||
if (rc < 0) { childmark(markerwrite, rc); };
|
if (rc < 0) { childmark(markerwrite, rc); };
|
||||||
if (launchmaskactive) {
|
if (launchmaskactive) {
|
||||||
@@ -218,6 +220,9 @@ fn child(c: *command, av: []*u8, ep: []*u8, outfd: i32,
|
|||||||
if (rc < 0) { childmark(markerwrite, rc); };
|
if (rc < 0) { childmark(markerwrite, rc); };
|
||||||
};
|
};
|
||||||
childclose(markerread, markerwrite);
|
childclose(markerread, markerwrite);
|
||||||
|
rc = os.dup2(infd, os.STDIN_FILENO);
|
||||||
|
if (rc < 0) { childmark(markerwrite, rc); };
|
||||||
|
childclose(infd, markerwrite);
|
||||||
rc = os.dup2(outfd, os.STDOUT_FILENO);
|
rc = os.dup2(outfd, os.STDOUT_FILENO);
|
||||||
if (rc < 0) { childmark(markerwrite, rc); };
|
if (rc < 0) { childmark(markerwrite, rc); };
|
||||||
rc = os.dup2(errfd, os.STDERR_FILENO);
|
rc = os.dup2(errfd, os.STDERR_FILENO);
|
||||||
@@ -238,21 +243,37 @@ export fn start(p: *process, c: *command) void = {
|
|||||||
p.hasdeadline = c.deadline.sec != 0i64 || c.deadline.nsec != 0i64;
|
p.hasdeadline = c.deadline.sec != 0i64 || c.deadline.nsec != 0i64;
|
||||||
p.grace = c.grace;
|
p.grace = c.grace;
|
||||||
if (!valid(c)) { fail(p, 22); return; };
|
if (!valid(c)) { fail(p, 22); return; };
|
||||||
|
let stdinpath: str = c.stdinpath;
|
||||||
|
if (stdinpath.len == 0) { stdinpath = "/dev/null"; };
|
||||||
|
let infd: i32 = os.open(stdinpath, os.flag.RDONLY, 0i32);
|
||||||
|
if (infd < 0) { fail(p, infd); return; };
|
||||||
|
infd = safefd(&p.result, infd);
|
||||||
|
if (infd < 0) { fail(p, infd); return; };
|
||||||
let outfd: i32 = os.open(c.stdoutpath,
|
let outfd: i32 = os.open(c.stdoutpath,
|
||||||
os.flag.WRONLY | os.flag.CREATE | os.flag.EXCL, 384);
|
os.flag.WRONLY | os.flag.CREATE | os.flag.EXCL, 384);
|
||||||
if (outfd < 0) { fail(p, outfd); return; };
|
if (outfd < 0) {
|
||||||
|
fail(p, outfd);
|
||||||
|
closefd(&p.result, infd);
|
||||||
|
return;
|
||||||
|
};
|
||||||
outfd = safefd(&p.result, outfd);
|
outfd = safefd(&p.result, outfd);
|
||||||
if (outfd < 0) { fail(p, outfd); return; };
|
if (outfd < 0) {
|
||||||
|
fail(p, outfd);
|
||||||
|
closefd(&p.result, infd);
|
||||||
|
return;
|
||||||
|
};
|
||||||
let errfd: i32 = os.open(c.stderrpath,
|
let errfd: i32 = os.open(c.stderrpath,
|
||||||
os.flag.WRONLY | os.flag.CREATE | os.flag.EXCL, 384);
|
os.flag.WRONLY | os.flag.CREATE | os.flag.EXCL, 384);
|
||||||
if (errfd < 0) {
|
if (errfd < 0) {
|
||||||
fail(p, errfd);
|
fail(p, errfd);
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
errfd = safefd(&p.result, errfd);
|
errfd = safefd(&p.result, errfd);
|
||||||
if (errfd < 0) {
|
if (errfd < 0) {
|
||||||
fail(p, errfd);
|
fail(p, errfd);
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -260,6 +281,7 @@ export fn start(p: *process, c: *command) void = {
|
|||||||
let rc: i32 = os.pipe2(&marker, os.O_CLOEXEC | os.O_NONBLOCK);
|
let rc: i32 = os.pipe2(&marker, os.O_CLOEXEC | os.O_NONBLOCK);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fail(p, rc);
|
fail(p, rc);
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
closefd(&p.result, errfd);
|
closefd(&p.result, errfd);
|
||||||
return;
|
return;
|
||||||
@@ -267,6 +289,7 @@ export fn start(p: *process, c: *command) void = {
|
|||||||
marker[0] = safefd(&p.result, marker[0]);
|
marker[0] = safefd(&p.result, marker[0]);
|
||||||
if (marker[0] < 0) {
|
if (marker[0] < 0) {
|
||||||
fail(p, marker[0]);
|
fail(p, marker[0]);
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
closefd(&p.result, errfd);
|
closefd(&p.result, errfd);
|
||||||
closefd(&p.result, marker[1]);
|
closefd(&p.result, marker[1]);
|
||||||
@@ -275,6 +298,7 @@ export fn start(p: *process, c: *command) void = {
|
|||||||
marker[1] = safefd(&p.result, marker[1]);
|
marker[1] = safefd(&p.result, marker[1]);
|
||||||
if (marker[1] < 0) {
|
if (marker[1] < 0) {
|
||||||
fail(p, marker[1]);
|
fail(p, marker[1]);
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
closefd(&p.result, errfd);
|
closefd(&p.result, errfd);
|
||||||
closefd(&p.result, marker[0]);
|
closefd(&p.result, marker[0]);
|
||||||
@@ -285,16 +309,20 @@ export fn start(p: *process, c: *command) void = {
|
|||||||
let pid: i32 = os.fork();
|
let pid: i32 = os.fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
fail(p, pid);
|
fail(p, pid);
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
closefd(&p.result, errfd);
|
closefd(&p.result, errfd);
|
||||||
closefd(&p.result, marker[0]);
|
closefd(&p.result, marker[0]);
|
||||||
closefd(&p.result, marker[1]);
|
closefd(&p.result, marker[1]);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (pid == 0) { child(c, av, ep, outfd, errfd, marker[0], marker[1]); };
|
if (pid == 0) {
|
||||||
|
child(c, av, ep, infd, outfd, errfd, marker[0], marker[1]);
|
||||||
|
};
|
||||||
p.pid = pid;
|
p.pid = pid;
|
||||||
p.state = state.RUNNING as i32;
|
p.state = state.RUNNING as i32;
|
||||||
p.markerfd = marker[0];
|
p.markerfd = marker[0];
|
||||||
|
closefd(&p.result, infd);
|
||||||
closefd(&p.result, outfd);
|
closefd(&p.result, outfd);
|
||||||
closefd(&p.result, errfd);
|
closefd(&p.result, errfd);
|
||||||
closefd(&p.result, marker[1]);
|
closefd(&p.result, marker[1]);
|
||||||
|
|||||||
Reference in New Issue
Block a user