fix: inherit redirected console in SYS_SPAWN_CAPS
This commit is contained in:
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#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);
|
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,
|
static int Sys_Spawn(const char* path, const char* args,
|
||||||
const char* environment = nullptr, uint32_t environmentLength = 0) {
|
const char* environment = nullptr, uint32_t environmentLength = 0) {
|
||||||
char resolved[256];
|
char resolved[256];
|
||||||
@@ -55,33 +92,8 @@ namespace montauk::abi {
|
|||||||
environment, environmentLength);
|
environment, environmentLength);
|
||||||
if (childPid < 0) return childPid;
|
if (childPid < 0) return childPid;
|
||||||
|
|
||||||
if (inheritRedirection) {
|
if (inheritRedirection)
|
||||||
auto* child = Sched::GetProcessByPid(childPid);
|
return InheritRedirection(childPid, parent, parentSlot);
|
||||||
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;
|
return childPid;
|
||||||
}
|
}
|
||||||
@@ -115,8 +127,17 @@ namespace montauk::abi {
|
|||||||
|
|
||||||
char resolved[256];
|
char resolved[256];
|
||||||
if (!ResolveProcessPath(path, resolved, sizeof(resolved))) return -1;
|
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]).
|
// Copy the absolute path this process was spawned from (argv[0]).
|
||||||
|
|||||||
Reference in New Issue
Block a user