diff options
Diffstat (limited to 'src/ninep')
| -rw-r--r-- | src/ninep/ctl.zig | 16 | ||||
| -rw-r--r-- | src/ninep/pty.zig | 8 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 31382279..92342525 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -1996,7 +1996,7 @@ test "pty/ctl exec in a directory that is gone fails ENOENT; a shell that cannot try testing.expectEqualStrings("shell: access denied", p.fs.late_failure[0..p.fs.late_failure_len]); } -test "a script whose interpreter is not there: Tty refuses it up front, only an err logged" { +test "a script whose interpreter is not there: Tty refuses it up front, only an err logged, and pty/ctl exec keeps the running shell" { const p = try th.withTerm(testing.allocator); defer p.deinit(); const Starting = struct { @@ -2023,6 +2023,20 @@ test "a script whose interpreter is not there: Tty refuses it up front, only an try testing.expect(th.logHas(p, "Tty: interpreter /no/such/interp not found\n")); try testing.expect(!th.logHas(p, "\nmsg ")); try testing.expect(!th.logHas(p, "\ndel ")); + // The shell to start again is that script: refused before the running + // one goes. + const id = p.paneBySerial(serial).?; + p.panes[id].?.shell = try p.gpa.dupe(u8, try std.fmt.bufPrint(&line, "{s}/bad", .{dir})); + p.setCwd(id, dir); + const exec_refused = wr(p, Node.of(serial, .pty_ctl), "exec\n"); + try testing.expectEqual(E.NOENT, exec_refused.errno()); + try testing.expectEqualStrings("exec: interpreter /no/such/interp not found", exec_refused.reply.ename); + // One the host found could not start (the script changed after): said + // with the interpreter's name, and the running shell is not gone. + p.fs.late_failure_len = 0; + p.restartFailed(@intCast(id), error.InterpreterNotFound); + try testing.expectEqualStrings("shell: interpreter /no/such/interp not found", p.fs.late_failure[0..p.fs.late_failure_len]); + try testing.expect(!p.panes[id].?.shell_failed); } test "every EINVAL a write gets says why, in its err record too; DEL is a control character in a line" { diff --git a/src/ninep/pty.zig b/src/ninep/pty.zig index aa0f499a..bf5f432c 100644 --- a/src/ninep/pty.zig +++ b/src/ninep/pty.zig @@ -67,6 +67,14 @@ pub fn writeCtl(p: *Pardes, req: Req, id: usize) Reply { const dir = pane.cwdSlice(); return tree.failText(req.tag, E.NOENT, std.fmt.bufPrint(&p.fs.ename, "exec: {s}: no such directory", .{dir[0..@min(dir.len, 256)]}) catch "exec: no such directory"); }; + // Nor is a shell that is not there, or a script whose + // interpreter is not: refused, and the running shell kept. + if (comptime pardes.hosted) if (!apply and std.mem.eql(u8, line, "exec")) if (p.panes[id]) |pane| { + const bin = pane.shell orelse p.shellBin(); + var why: [320]u8 = undefined; + if (@import("../host_io.zig").Shell.refusal(bin[0..@min(bin.len, 200)], &why)) |refused| + return tree.failText(req.tag, E.NOENT, std.fmt.bufPrint(&p.fs.ename, "exec: {s}", .{refused}) catch "exec: no such shell"); + }; if (!verb(p, id, line, apply)) return tree.failText(req.tag, E.INVAL, if (outOfRange(line)) e_winsize_range else e_bad_pty_ctl); } } |
