shell can launch another user processgit add .git add .!
This commit is contained in:
@@ -12,6 +12,7 @@ typedef enum {
|
||||
STATE_SLEEPING = 2,
|
||||
STATE_BLOCKED = 3,
|
||||
STATE_DEAD = 4,
|
||||
STATE_ZOMBIE = 5,
|
||||
} process_state_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -32,6 +33,8 @@ typedef struct process_t {
|
||||
uint32_t flags;
|
||||
file_t* fd_table[MAX_PROCESS_FDS];
|
||||
struct process_t* sched_next;
|
||||
struct process_t* waiting;
|
||||
int exit_status;
|
||||
} __attribute__((packed)) process_t;
|
||||
|
||||
#endif
|
||||
@@ -186,4 +186,13 @@ void wake(process_t* task) {
|
||||
if (task->state == STATE_SLEEPING || task->state == STATE_BLOCKED) {
|
||||
task->state = STATE_READY;
|
||||
}
|
||||
}
|
||||
|
||||
process_t* get_task_by_pid(uint32_t pid) {
|
||||
process_t* cur = process_table;
|
||||
while (cur) {
|
||||
if (cur->pid == pid) break;
|
||||
cur = cur->sched_next;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ void init_scheduler();
|
||||
void init_task(process_t* process, uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp);
|
||||
|
||||
process_t* current_task();
|
||||
process_t* get_task_by_pid(uint32_t pid);
|
||||
|
||||
int get_next_pid();
|
||||
void add_task(process_t* task);
|
||||
|
||||
@@ -25,7 +25,11 @@ typedef struct registers {
|
||||
|
||||
static int32_t sys_exit(int status) {
|
||||
process_t* task = current_task();
|
||||
task->state = STATE_DEAD;
|
||||
task->state = STATE_ZOMBIE;
|
||||
task->exit_status = status;
|
||||
if (task->waiting) {
|
||||
wake(task->waiting);
|
||||
}
|
||||
exit();
|
||||
return 0;
|
||||
}
|
||||
@@ -163,6 +167,9 @@ static int32_t sys_exec(registers_t* regs, const char* prgm) {
|
||||
clear_current_pd();
|
||||
|
||||
uint32_t eip = load_elf_program(prgm);
|
||||
if (eip == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t stack_sz = PAGE_SIZE * 16;
|
||||
uint32_t stack_top = 0xBFFF0000;
|
||||
@@ -204,6 +211,16 @@ static int32_t sys_lseek(int fd, size_t offset, int whence) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t sys_waitpid(int pid, int* exit_status) {
|
||||
process_t* current = current_task();
|
||||
process_t* child = get_task_by_pid(pid);
|
||||
current->state = STATE_BLOCKED;
|
||||
child->waiting = current;
|
||||
yield();
|
||||
*exit_status = child->exit_status;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void syscall(registers_t* regs) {
|
||||
int32_t ret;
|
||||
switch(regs->eax) {
|
||||
@@ -218,6 +235,7 @@ void syscall(registers_t* regs) {
|
||||
case 22: ret = sys_exec(regs, (const char*)regs->ebx); break;
|
||||
case 23: ret = sys_dup2(regs->ebx, regs->ecx); break;
|
||||
case 24: ret = sys_lseek(regs->ebx, regs->ecx, regs->edx); break;
|
||||
case 25: ret = sys_waitpid(regs->ebx, (int*)regs->ecx); break;
|
||||
default: ret = -1;
|
||||
}
|
||||
regs->eax = ret;
|
||||
|
||||
Reference in New Issue
Block a user