sh: Improve it
This commit is contained in:
parent
3c5c92c7c3
commit
7e9744419e
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user