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