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 <sys/wait.h>
#include <unistd.h> #include <unistd.h>
static int status;
typedef struct typedef struct
{ {
char* buffer; char* buffer;
@ -13,7 +15,7 @@ typedef struct
void show_prompt() void show_prompt()
{ {
printf("> "); printf("[%ld]> ", getpid());
} }
void command_expand(command* cmd, long new_capacity) void command_expand(command* cmd, long new_capacity)
@ -70,7 +72,6 @@ void command_execute(command* cmd)
perror(cmd->buffer); perror(cmd->buffer);
exit(127); exit(127);
} }
int status;
pid_t result; pid_t result;
while ((result = waitpid(child, &status, 0)) == 0) { msleep(20); } while ((result = waitpid(child, &status, 0)) == 0) { msleep(20); }
if (result < 0) if (result < 0)
@ -80,7 +81,10 @@ void command_execute(command* cmd)
show_prompt(); show_prompt();
return; 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); command_clear(cmd);
show_prompt(); show_prompt();
} }

View File

@ -134,12 +134,19 @@ void AddressSpace::clear()
kdbgln("Reclaimed %ld pages from address space!", pages_freed); 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 AddressSpace::clone() // FIXME: Add out-of-memory checks to this function.
{ {
AddressSpace result; AddressSpace result;
result.m_pml4 = (PageTable*)PMM::request_page(); result.m_pml4 = try_clone_page_table(m_pml4);
if (!result.m_pml4) return result; if (!result.m_pml4) return result;
memcpy(result.m_pml4, m_pml4, PAGE_SIZE);
for (int i = 0; i < 512; i++) for (int i = 0; i < 512; i++)
{ {
PageDirectoryEntry& pdp_pde = m_pml4->entries[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.present) continue;
if (pdp_pde.larger_pages) if (pdp_pde.larger_pages)
{ {
void* cloned = PMM::request_page(); void* cloned = try_clone_page_table((PageTable*)pdp_pde.get_address());
memcpy(cloned, (void*)pdp_pde.get_address(), PAGE_SIZE); if (!cloned)
{
cloned_pdp_pde.present = false;
continue;
}
cloned_pdp_pde.set_address((uint64_t)cloned); cloned_pdp_pde.set_address((uint64_t)cloned);
continue; continue;
} }
PageTable* pdp = (PageTable*)pdp_pde.get_address(); PageTable* pdp = (PageTable*)pdp_pde.get_address();
PageTable* cloned_pdp = (PageTable*)PMM::request_page(); PageTable* cloned_pdp = try_clone_page_table(pdp);
memcpy(cloned_pdp, pdp, PAGE_SIZE); if (!cloned_pdp)
{
cloned_pdp_pde.present = false;
continue;
}
cloned_pdp_pde.set_address((uint64_t)cloned_pdp); 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 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.present) continue;
if (pd_pde.larger_pages) if (pd_pde.larger_pages)
{ {
void* cloned = PMM::request_page(); void* cloned = try_clone_page_table((PageTable*)pd_pde.get_address());
memcpy(cloned, (void*)pd_pde.get_address(), PAGE_SIZE); if (!cloned)
{
cloned_pd_pde.present = false;
continue;
}
cloned_pd_pde.set_address((uint64_t)cloned); cloned_pd_pde.set_address((uint64_t)cloned);
continue; continue;
} }
PageTable* pd = (PageTable*)pd_pde.get_address(); PageTable* pd = (PageTable*)pd_pde.get_address();
PageTable* cloned_pd = (PageTable*)PMM::request_page(); PageTable* cloned_pd = try_clone_page_table(pd);
memcpy(cloned_pd, pd, PAGE_SIZE); if (!cloned_pd)
{
cloned_pd_pde.present = false;
continue;
}
cloned_pd_pde.set_address((uint64_t)cloned_pd); cloned_pd_pde.set_address((uint64_t)cloned_pd);
for (int k = 0; k < 512; k++) 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.present) continue;
if (pt_pde.larger_pages) if (pt_pde.larger_pages)
{ {
void* cloned = PMM::request_page(); void* cloned = try_clone_page_table((PageTable*)pt_pde.get_address());
memcpy(cloned, (void*)pt_pde.get_address(), PAGE_SIZE); if (!cloned)
{
cloned_pt_pde.present = false;
continue;
}
cloned_pt_pde.set_address((uint64_t)cloned); cloned_pt_pde.set_address((uint64_t)cloned);
continue; continue;
} }
PageTable* pt = (PageTable*)pt_pde.get_address(); PageTable* pt = (PageTable*)pt_pde.get_address();
PageTable* cloned_pt = (PageTable*)PMM::request_page(); PageTable* cloned_pt = try_clone_page_table(pt);
memcpy(cloned_pt, pt, PAGE_SIZE); if (!cloned_pt)
{
cloned_pt_pde.present = false;
continue;
}
cloned_pt_pde.set_address((uint64_t)cloned_pt); cloned_pt_pde.set_address((uint64_t)cloned_pt);
for (int l = 0; l < 512; l++) for (int l = 0; l < 512; l++)
{ {
PageDirectoryEntry& pde = pt->entries[l]; PageDirectoryEntry& pde = pt->entries[l];
PageDirectoryEntry& cloned_pde = cloned_pt->entries[l]; PageDirectoryEntry& cloned_pde = cloned_pt->entries[l];
if (!pde.present) continue; if (!pde.present) continue;
void* cloned = PMM::request_page(); void* cloned = try_clone_page_table((PageTable*)pde.get_address());
memcpy(cloned, (void*)pde.get_address(), PAGE_SIZE); if (!cloned)
{
cloned_pde.present = false;
continue;
}
cloned_pde.set_address((uint64_t)cloned); cloned_pde.set_address((uint64_t)cloned);
continue; continue;
} }

View File

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