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
|
||||
// environment, and an empty dir inherits the caller's working directory.
|
||||
// stdoutpath and stderrpath are created exclusively with mode 0600. A zero
|
||||
// deadline means no timeout.
|
||||
// An empty stdinpath selects the null device; stdoutpath and stderrpath are
|
||||
// created exclusively with mode 0600. A zero deadline means no timeout.
|
||||
export type command = struct {
|
||||
path: str,
|
||||
argv: []str,
|
||||
env: []str,
|
||||
dir: str,
|
||||
stdinpath: str,
|
||||
stdoutpath: str,
|
||||
stderrpath: str,
|
||||
deadline: time.instant,
|
||||
@@ -124,7 +125,8 @@ fn valid(c: *command) bool = {
|
||||
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)) {
|
||||
return false;
|
||||
};
|
||||
@@ -209,8 +211,8 @@ fn childclose(fd: i32, markerfd: i32) void = {
|
||||
if (rc < 0) { childmark(markerfd, rc); };
|
||||
};
|
||||
|
||||
fn child(c: *command, av: []*u8, ep: []*u8, outfd: i32,
|
||||
errfd: i32, markerread: i32, markerwrite: i32) void = {
|
||||
fn child(c: *command, av: []*u8, ep: []*u8, infd: i32,
|
||||
outfd: i32, errfd: i32, markerread: i32, markerwrite: i32) void = {
|
||||
let rc: i32 = os.setpgid(0, 0);
|
||||
if (rc < 0) { childmark(markerwrite, rc); };
|
||||
if (launchmaskactive) {
|
||||
@@ -218,6 +220,9 @@ fn child(c: *command, av: []*u8, ep: []*u8, outfd: i32,
|
||||
if (rc < 0) { childmark(markerwrite, rc); };
|
||||
};
|
||||
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);
|
||||
if (rc < 0) { childmark(markerwrite, rc); };
|
||||
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.grace = c.grace;
|
||||
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,
|
||||
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);
|
||||
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,
|
||||
os.flag.WRONLY | os.flag.CREATE | os.flag.EXCL, 384);
|
||||
if (errfd < 0) {
|
||||
fail(p, errfd);
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
return;
|
||||
};
|
||||
errfd = safefd(&p.result, errfd);
|
||||
if (errfd < 0) {
|
||||
fail(p, errfd);
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
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);
|
||||
if (rc < 0) {
|
||||
fail(p, rc);
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
closefd(&p.result, errfd);
|
||||
return;
|
||||
@@ -267,6 +289,7 @@ export fn start(p: *process, c: *command) void = {
|
||||
marker[0] = safefd(&p.result, marker[0]);
|
||||
if (marker[0] < 0) {
|
||||
fail(p, marker[0]);
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
closefd(&p.result, errfd);
|
||||
closefd(&p.result, marker[1]);
|
||||
@@ -275,6 +298,7 @@ export fn start(p: *process, c: *command) void = {
|
||||
marker[1] = safefd(&p.result, marker[1]);
|
||||
if (marker[1] < 0) {
|
||||
fail(p, marker[1]);
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
closefd(&p.result, errfd);
|
||||
closefd(&p.result, marker[0]);
|
||||
@@ -285,16 +309,20 @@ export fn start(p: *process, c: *command) void = {
|
||||
let pid: i32 = os.fork();
|
||||
if (pid < 0) {
|
||||
fail(p, pid);
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
closefd(&p.result, errfd);
|
||||
closefd(&p.result, marker[0]);
|
||||
closefd(&p.result, marker[1]);
|
||||
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.state = state.RUNNING as i32;
|
||||
p.markerfd = marker[0];
|
||||
closefd(&p.result, infd);
|
||||
closefd(&p.result, outfd);
|
||||
closefd(&p.result, errfd);
|
||||
closefd(&p.result, marker[1]);
|
||||
|
||||
Reference in New Issue
Block a user