summaryrefslogtreecommitdiff
path: root/src/kernel/task
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/task')
-rw-r--r--src/kernel/task/task.cpp67
-rw-r--r--src/kernel/task/task.h3
2 files changed, 52 insertions, 18 deletions
diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp
index e513608..1a5d535 100644
--- a/src/kernel/task/task.cpp
+++ b/src/kernel/task/task.cpp
@@ -340,37 +340,36 @@ static void process_delete(process *pr) {
kfree(pr);
}
-size_t process_sbrk(size_t size) {
- process *p = current_process;
- if (p->data == 0) return -1;
- ASSERT(p->data < K_HIGHHALF_ADDR);
- if (p->data + size >= K_HIGHHALF_ADDR) return -1;
+size_t process::sbrk(size_t size) {
+ if (data == 0) return -1;
+ ASSERT(data < K_HIGHHALF_ADDR);
+ if (data + size >= K_HIGHHALF_ADDR) return -1;
size_t ret;
- if (p->dataseg == 0) {
- size_t start = p->data;
+ if (dataseg == 0) {
+ size_t start = data;
if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000;
size_t end = start + size;
if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000;
segment *s = new simpleseg(start, end - start, 1);
if (s == 0) return -5;
- p->dataseg = s->map(p->pagedir, 0);
- if (p->dataseg == 0) return -1;
+ dataseg = s->map(pagedir, 0);
+ if (dataseg == 0) return -1;
ret = start;
- p->data = start + size;
+ data = start + size;
} else {
- size_t start = p->dataseg->start;
- size_t end = p->data + size;
+ size_t start = dataseg->start;
+ size_t end = data + size;
if (end <= start) return -1;
if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000;
- simpleseg *s = (simpleseg*)(p->dataseg->seg);
- s->resize(p->dataseg, end - start);
+ simpleseg *s = (simpleseg*)(dataseg->seg);
+ s->resize(dataseg, end - start);
- ret = p->data;
- p->data += size;
+ ret = data;
+ data += size;
}
/* (DBG) ke_vt->writeStr("(sbrk ");
ke_vt->writeHex(size);
@@ -380,8 +379,40 @@ size_t process_sbrk(size_t size) {
return ret;
}
+void* process::set_args(char** args) {
+ if (args == 0) return 0;
+
+ cli(); // we're writing to this process's user space
+ page_directory *r = current_pagedir;
+ pagedir_switch(pagedir);
+
+ int len = sizeof(char*), argc = 0;
+ for (char** a = args; *a != 0; a++) {
+ len += strlen(*a) + 1 + sizeof(char*);
+ argc++;
+ }
+
+ void* p = (void*)sbrk(len);
+ char** si = (char**)p;
+ char* s = (char*)p + ((argc + 1) * sizeof(char*));
+ for (int i = 0; i < argc; i++) {
+ si[i] = s;
+ strcpy(s, args[i]);
+ s += strlen(args[i]) + 1;
+ }
+ si[argc] = 0;
+
+ pagedir_switch(r);
+ sti();
+
+ return p;
+}
+
+// syscalls
+size_t process_sbrk(size_t size) {
+ return current_process->sbrk(size);
+}
void process_brk(size_t ptr) {
ASSERT(ptr < K_HIGHHALF_ADDR);
- process_sbrk(ptr - current_process->data);
+ current_process->sbrk(ptr - current_process->data);
}
-
diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h
index 1c32657..99738b9 100644
--- a/src/kernel/task/task.h
+++ b/src/kernel/task/task.h
@@ -41,6 +41,9 @@ class process {
process() : fd(4, 4) {} // must not be used directly
process(process *parent, uint32_t uid, uint32_t privilege);
+
+ void* set_args(char** args);
+ size_t sbrk(size_t size);
};
class thread {