ww: give captured actions null stdin

This commit is contained in:
2026-08-20 17:39:06 +09:00
parent 6e9591d4b4
commit a8b88afcba

View File

@@ -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]);