mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 15:34:31 +00:00
refactor(kernel/syscalls): improve linux_execve implementation
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
2f18d390e4
commit
31181d5b5d
@ -1614,9 +1614,7 @@ static pid_t linux_vfork(SysFrm *sf)
|
|||||||
return (int)NewProcess->ID;
|
return (int)NewProcess->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathname,
|
__no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathname, char *const argv[], char *const envp[])
|
||||||
char *const argv[],
|
|
||||||
char *const envp[])
|
|
||||||
{
|
{
|
||||||
/* FIXME: exec doesn't follow the UNIX standard
|
/* FIXME: exec doesn't follow the UNIX standard
|
||||||
The pid, open files, etc. should be preserved */
|
The pid, open files, etc. should be preserved */
|
||||||
@ -1762,13 +1760,66 @@ __no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathn
|
|||||||
}
|
}
|
||||||
safeArgv[i] = nullptr;
|
safeArgv[i] = nullptr;
|
||||||
|
|
||||||
return ConvertErrnoToLinux(linux_execve(sf, safeArgv[0],
|
debug("calling linux_execve with %s", safeArgv[0]);
|
||||||
(char *const *)safeArgv,
|
|
||||||
(char *const *)safeEnvp));
|
PCB *newPcb = TaskManager->CreateProcess(pcb, safeArgv[0], Tasking::TaskExecutionMode::User, false, pcb->Security.Real.UserID, pcb->Security.Real.GroupID);
|
||||||
|
if (!newPcb)
|
||||||
|
{
|
||||||
|
error("Failed to create process for interpreter");
|
||||||
|
return -linux_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
newPcb->Security = pcb->Security;
|
||||||
|
newPcb->Info = pcb->Info;
|
||||||
|
newPcb->FileDescriptors = pcb->FileDescriptors;
|
||||||
|
newPcb->CWD = pcb->CWD;
|
||||||
|
newPcb->PageTable = pcb->PageTable;
|
||||||
|
newPcb->vma = pcb->vma;
|
||||||
|
newPcb->ProgramBreak = pcb->ProgramBreak;
|
||||||
|
|
||||||
|
char **newArgv = (char **)newPcb->vma->RequestPages(TO_PAGES(i * sizeof(char *)));
|
||||||
|
char **newEnvp = (char **)newPcb->vma->RequestPages(TO_PAGES(envpLen * sizeof(char *)));
|
||||||
|
|
||||||
|
for (int j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
size_t len = strlen(safeArgv[j]);
|
||||||
|
char *newArg = (char *)newPcb->vma->RequestPages(TO_PAGES(len));
|
||||||
|
memcpy(newArg, safeArgv[j], len);
|
||||||
|
newArg[len] = '\0';
|
||||||
|
newArgv[j] = newArg;
|
||||||
|
}
|
||||||
|
newArgv[i] = nullptr;
|
||||||
|
|
||||||
|
for (int j = 0; j < envpLen; j++)
|
||||||
|
{
|
||||||
|
size_t len = strlen(safeEnvp[j]);
|
||||||
|
char *newEnv = (char *)newPcb->vma->RequestPages(TO_PAGES(len));
|
||||||
|
memcpy(newEnv, safeEnvp[j], len);
|
||||||
|
newEnv[len] = '\0';
|
||||||
|
newEnvp[j] = newEnv;
|
||||||
|
}
|
||||||
|
newEnvp[envpLen] = nullptr;
|
||||||
|
|
||||||
|
int ret = Execute::Spawn((char *)safeArgv[0], (const char **)newArgv, (const char **)newEnvp,
|
||||||
|
newPcb, true, newPcb->Info.Compatibility);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
error("Failed to spawn interpreter");
|
||||||
|
return ConvertErrnoToLinux(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetCurrentCPU()->CurrentProcess = newPcb;
|
||||||
|
GetCurrentCPU()->CurrentThread = newPcb->Threads[0];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
newPcb->GetContext()->Yield();
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcb->Linux.vforked)
|
if (pcb->Linux.vforked)
|
||||||
{
|
{
|
||||||
|
debug("vforked: %s", pPathname);
|
||||||
CriticalSection cs;
|
CriticalSection cs;
|
||||||
|
|
||||||
pcb->Linux.CallingThread->SetState(Tasking::Ready);
|
pcb->Linux.CallingThread->SetState(Tasking::Ready);
|
||||||
@ -1777,14 +1828,11 @@ __no_sanitize("undefined") static int linux_execve(SysFrm *sf, const char *pathn
|
|||||||
pcb->PageTable = KernelPageTable->Fork();
|
pcb->PageTable = KernelPageTable->Fork();
|
||||||
pcb->vma = new Memory::VirtualMemoryArea(pcb->PageTable);
|
pcb->vma = new Memory::VirtualMemoryArea(pcb->PageTable);
|
||||||
pcb->ProgramBreak = new Memory::ProgramBreak(pcb->PageTable, pcb->vma);
|
pcb->ProgramBreak = new Memory::ProgramBreak(pcb->PageTable, pcb->vma);
|
||||||
// tcb->Stack = new Memory::StackGuard(true, pcb->vma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = Execute::Spawn((char *)pPathname,
|
debug("spawn(%s %#lx %#lx %#lx %d %d)", pPathname, safeArgv, safeEnvp, pcb, true, pcb->Info.Compatibility);
|
||||||
(const char **)safeArgv,
|
int ret = Execute::Spawn((char *)pPathname, (const char **)safeArgv, (const char **)safeEnvp,
|
||||||
(const char **)safeEnvp,
|
pcb, true, pcb->Info.Compatibility);
|
||||||
pcb, true,
|
|
||||||
pcb->Info.Compatibility);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user