fix: inherit redirected console in SYS_SPAWN_CAPS
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 177
|
||||
#define MONTAUK_BUILD_NUMBER 178
|
||||
|
||||
+50
-29
@@ -43,6 +43,43 @@ namespace montauk::abi {
|
||||
return Sched::LookupExitCode(pid);
|
||||
}
|
||||
|
||||
// Hand a freshly spawned child the parent's redirected console. Both spawn
|
||||
// syscalls need this: a console tool launched from a GUI terminal must read
|
||||
// its keys from the terminal's mailbox and write its output back up the
|
||||
// stream, whether or not it also carries a capability grant. The child is
|
||||
// created suspended (startReady == false) so its first instruction cannot
|
||||
// run before the channels exist, and is started here once they do.
|
||||
// Returns childPid, or kills the child and returns -1 on failure.
|
||||
static int InheritRedirection(int childPid, Sched::Process* parent, int parentSlot) {
|
||||
auto* child = Sched::GetProcessByPid(childPid);
|
||||
int childSlot = Ipc::SlotForPid(childPid);
|
||||
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
|
||||
Sched::KillProcess(childPid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
child->ioOutHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioOutHandle, childSlot);
|
||||
child->ioInHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioInHandle, childSlot);
|
||||
child->ioKeyHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioKeyHandle, childSlot);
|
||||
|
||||
if (child->ioOutHandle < 0 || child->ioInHandle < 0 || child->ioKeyHandle < 0 ||
|
||||
!ConfigureRedirWaitsetForSlot(childSlot, child)) {
|
||||
Sched::KillProcess(childPid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
child->redirected = true;
|
||||
child->parentPid = parent->pid;
|
||||
child->termCols = parent->termCols;
|
||||
child->termRows = parent->termRows;
|
||||
if (Sched::StartProcess(childPid) < 0) {
|
||||
Sched::KillProcess(childPid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return childPid;
|
||||
}
|
||||
|
||||
static int Sys_Spawn(const char* path, const char* args,
|
||||
const char* environment = nullptr, uint32_t environmentLength = 0) {
|
||||
char resolved[256];
|
||||
@@ -55,33 +92,8 @@ namespace montauk::abi {
|
||||
environment, environmentLength);
|
||||
if (childPid < 0) return childPid;
|
||||
|
||||
if (inheritRedirection) {
|
||||
auto* child = Sched::GetProcessByPid(childPid);
|
||||
int childSlot = Ipc::SlotForPid(childPid);
|
||||
if (child == nullptr || childSlot < 0 || parentSlot < 0) {
|
||||
Sched::KillProcess(childPid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
child->ioOutHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioOutHandle, childSlot);
|
||||
child->ioInHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioInHandle, childSlot);
|
||||
child->ioKeyHandle = DuplicateHandleBetweenSlots(parentSlot, parent->ioKeyHandle, childSlot);
|
||||
|
||||
if (child->ioOutHandle < 0 || child->ioInHandle < 0 || child->ioKeyHandle < 0 ||
|
||||
!ConfigureRedirWaitsetForSlot(childSlot, child)) {
|
||||
Sched::KillProcess(childPid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
child->redirected = true;
|
||||
child->parentPid = parent->pid;
|
||||
child->termCols = parent->termCols;
|
||||
child->termRows = parent->termRows;
|
||||
if (Sched::StartProcess(childPid) < 0) {
|
||||
Sched::KillProcess(childPid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (inheritRedirection)
|
||||
return InheritRedirection(childPid, parent, parentSlot);
|
||||
|
||||
return childPid;
|
||||
}
|
||||
@@ -115,8 +127,17 @@ namespace montauk::abi {
|
||||
|
||||
char resolved[256];
|
||||
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
|
||||
return Sched::Spawn(resolved, args, true, nullptr, 0, ©,
|
||||
userOverride);
|
||||
|
||||
int parentSlot = Ipc::CurrentSlot();
|
||||
bool inheritRedirection = parent->redirected;
|
||||
int childPid = Sched::Spawn(resolved, args, !inheritRedirection,
|
||||
nullptr, 0, ©, userOverride);
|
||||
if (childPid < 0) return childPid;
|
||||
|
||||
if (inheritRedirection)
|
||||
return InheritRedirection(childPid, parent, parentSlot);
|
||||
|
||||
return childPid;
|
||||
}
|
||||
|
||||
// Copy the absolute path this process was spawned from (argv[0]).
|
||||
|
||||
Reference in New Issue
Block a user