sh: Improve it

This commit is contained in:
apio 2022-10-19 20:16:21 +02:00
parent 3c5c92c7c3
commit 7e9744419e
3 changed files with 61 additions and 19 deletions

View File

@ -4,6 +4,8 @@
#include <sys/wait.h>
#include <unistd.h>
static int status;
typedef struct
{
char* buffer;
@ -13,7 +15,7 @@ typedef struct
void show_prompt()
{
printf("> ");
printf("[%ld]> ", getpid());
}
void command_expand(command* cmd, long new_capacity)
@ -70,7 +72,6 @@ void command_execute(command* cmd)
perror(cmd->buffer);
exit(127);
}
int status;
pid_t result;
while ((result = waitpid(child, &status, 0)) == 0) { msleep(20); }
if (result < 0)
@ -80,7 +81,10 @@ void command_execute(command* cmd)
show_prompt();
return;
}
if (WEXITSTATUS(status) != 0) { printf("Exited with code %d\n", WEXITSTATUS(status)); }
int exit_status = WEXITSTATUS(status);
if (exit_status == -2 || exit_status == -3) printf("(PID %ld) Segmentation fault\n", result);
else if (exit_status)
printf("Exited with code %d\n", WEXITSTATUS(status));
command_clear(cmd);
show_prompt();
}

View File

@ -134,12 +134,19 @@ void AddressSpace::clear()
kdbgln("Reclaimed %ld pages from address space!", pages_freed);
}
static PageTable* try_clone_page_table(PageTable* source)
{
PageTable* dst = (PageTable*)PMM::request_page();
if (PMM_DID_FAIL(dst)) { return 0; }
memcpy(dst, source, sizeof(PageTable));
return dst;
}
AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this function.
{
AddressSpace result;
result.m_pml4 = (PageTable*)PMM::request_page();
result.m_pml4 = try_clone_page_table(m_pml4);
if (!result.m_pml4) return result;
memcpy(result.m_pml4, m_pml4, PAGE_SIZE);
for (int i = 0; i < 512; i++)
{
PageDirectoryEntry& pdp_pde = m_pml4->entries[i];
@ -147,14 +154,22 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu
if (!pdp_pde.present) continue;
if (pdp_pde.larger_pages)
{
void* cloned = PMM::request_page();
memcpy(cloned, (void*)pdp_pde.get_address(), PAGE_SIZE);
void* cloned = try_clone_page_table((PageTable*)pdp_pde.get_address());
if (!cloned)
{
cloned_pdp_pde.present = false;
continue;
}
cloned_pdp_pde.set_address((uint64_t)cloned);
continue;
}
PageTable* pdp = (PageTable*)pdp_pde.get_address();
PageTable* cloned_pdp = (PageTable*)PMM::request_page();
memcpy(cloned_pdp, pdp, PAGE_SIZE);
PageTable* cloned_pdp = try_clone_page_table(pdp);
if (!cloned_pdp)
{
cloned_pdp_pde.present = false;
continue;
}
cloned_pdp_pde.set_address((uint64_t)cloned_pdp);
for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one
{
@ -163,14 +178,22 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu
if (!pd_pde.present) continue;
if (pd_pde.larger_pages)
{
void* cloned = PMM::request_page();
memcpy(cloned, (void*)pd_pde.get_address(), PAGE_SIZE);
void* cloned = try_clone_page_table((PageTable*)pd_pde.get_address());
if (!cloned)
{
cloned_pd_pde.present = false;
continue;
}
cloned_pd_pde.set_address((uint64_t)cloned);
continue;
}
PageTable* pd = (PageTable*)pd_pde.get_address();
PageTable* cloned_pd = (PageTable*)PMM::request_page();
memcpy(cloned_pd, pd, PAGE_SIZE);
PageTable* cloned_pd = try_clone_page_table(pd);
if (!cloned_pd)
{
cloned_pd_pde.present = false;
continue;
}
cloned_pd_pde.set_address((uint64_t)cloned_pd);
for (int k = 0; k < 512; k++)
{
@ -179,22 +202,34 @@ AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this fu
if (!pt_pde.present) continue;
if (pt_pde.larger_pages)
{
void* cloned = PMM::request_page();
memcpy(cloned, (void*)pt_pde.get_address(), PAGE_SIZE);
void* cloned = try_clone_page_table((PageTable*)pt_pde.get_address());
if (!cloned)
{
cloned_pt_pde.present = false;
continue;
}
cloned_pt_pde.set_address((uint64_t)cloned);
continue;
}
PageTable* pt = (PageTable*)pt_pde.get_address();
PageTable* cloned_pt = (PageTable*)PMM::request_page();
memcpy(cloned_pt, pt, PAGE_SIZE);
PageTable* cloned_pt = try_clone_page_table(pt);
if (!cloned_pt)
{
cloned_pt_pde.present = false;
continue;
}
cloned_pt_pde.set_address((uint64_t)cloned_pt);
for (int l = 0; l < 512; l++)
{
PageDirectoryEntry& pde = pt->entries[l];
PageDirectoryEntry& cloned_pde = cloned_pt->entries[l];
if (!pde.present) continue;
void* cloned = PMM::request_page();
memcpy(cloned, (void*)pde.get_address(), PAGE_SIZE);
void* cloned = try_clone_page_table((PageTable*)pde.get_address());
if (!cloned)
{
cloned_pde.present = false;
continue;
}
cloned_pde.set_address((uint64_t)cloned);
continue;
}

View File

@ -485,12 +485,15 @@ void sys_waitpid(Context* context, long pid, int* wstatus,
}
if (wstatus)
{
VMM::switch_to_user_address_space(sched_current_task->address_space);
VMM::enter_syscall_context();
int* kwstatus = obtain_user_ref(wstatus);
if (kwstatus)
{
*kwstatus = (int)(child->exit_status & 0xff);
release_user_ref(kwstatus);
}
else { kinfoln("wstatus ptr is invalid: %p", (void*)wstatus); }
}
child->state = child->Exited;
context->rax = (long)child->id;