SIGNALS
This commit is contained in:
parent
a09be369ea
commit
65fa12f482
@ -42,6 +42,7 @@ typedef struct image {
|
|||||||
uintptr_t heap_actual; /* Actual heap location */
|
uintptr_t heap_actual; /* Actual heap location */
|
||||||
uintptr_t stack; /* Process kernel stack */
|
uintptr_t stack; /* Process kernel stack */
|
||||||
uintptr_t user_stack; /* User stack */
|
uintptr_t user_stack; /* User stack */
|
||||||
|
uintptr_t start;
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
/* Resizable descriptor table */
|
/* Resizable descriptor table */
|
||||||
@ -56,7 +57,7 @@ typedef struct descriptor_table {
|
|||||||
|
|
||||||
/* Signal Table */
|
/* Signal Table */
|
||||||
typedef struct signal_table {
|
typedef struct signal_table {
|
||||||
uintptr_t * functions[NUMSIGNALS];
|
uintptr_t functions[NUMSIGNALS];
|
||||||
} sig_table_t;
|
} sig_table_t;
|
||||||
|
|
||||||
/* Portable process struct */
|
/* Portable process struct */
|
||||||
@ -78,6 +79,9 @@ typedef struct process {
|
|||||||
struct regs * syscall_registers; /* Registers at interrupt */
|
struct regs * syscall_registers; /* Registers at interrupt */
|
||||||
list_t * wait_queue;
|
list_t * wait_queue;
|
||||||
list_t * shm_mappings; /* Shared memory chunk mappings */
|
list_t * shm_mappings; /* Shared memory chunk mappings */
|
||||||
|
list_t * signal_queue; /* Queued signals */
|
||||||
|
thread_t signal_state;
|
||||||
|
char * signal_kstack;
|
||||||
} process_t;
|
} process_t;
|
||||||
|
|
||||||
void initialize_process_tree();
|
void initialize_process_tree();
|
||||||
@ -95,6 +99,7 @@ uint32_t process_append_fd(process_t * proc, fs_node_t * node);
|
|||||||
process_t * process_from_pid(pid_t pid);
|
process_t * process_from_pid(pid_t pid);
|
||||||
void delete_process(process_t * proc);
|
void delete_process(process_t * proc);
|
||||||
uint32_t process_move_fd(process_t * proc, int src, int dest);
|
uint32_t process_move_fd(process_t * proc, int src, int dest);
|
||||||
|
int XXX_slow_process_is_queued(process_t * proc);
|
||||||
|
|
||||||
volatile process_t * current_process;
|
volatile process_t * current_process;
|
||||||
|
|
||||||
|
@ -107,6 +107,8 @@ struct regs {
|
|||||||
unsigned int eip, cs, eflags, useresp, ss;
|
unsigned int eip, cs, eflags, useresp, ss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct regs regs_t;
|
||||||
|
|
||||||
typedef void (*irq_handler_t) (struct regs *);
|
typedef void (*irq_handler_t) (struct regs *);
|
||||||
|
|
||||||
/* Panic */
|
/* Panic */
|
||||||
@ -357,4 +359,10 @@ typedef struct {
|
|||||||
int wakeup_queue(list_t * queue);
|
int wakeup_queue(list_t * queue);
|
||||||
int sleep_on(list_t * queue);
|
int sleep_on(list_t * queue);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t signum;
|
||||||
|
uintptr_t handler;
|
||||||
|
regs_t registers_before;
|
||||||
|
} signal_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#define KERNEL_HEAP_END 0x02000000
|
#define KERNEL_HEAP_END 0x02000000
|
||||||
|
|
||||||
@ -305,6 +306,11 @@ page_fault(
|
|||||||
uint32_t faulting_address;
|
uint32_t faulting_address;
|
||||||
asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
|
asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
|
||||||
|
|
||||||
|
if (r->eip == 0xFFFFFFFF) {
|
||||||
|
return_from_signal_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
int present = !(r->err_code & 0x1);
|
int present = !(r->err_code & 0x1);
|
||||||
int rw = r->err_code & 0x2;
|
int rw = r->err_code & 0x2;
|
||||||
int user = r->err_code & 0x4;
|
int user = r->err_code & 0x4;
|
||||||
@ -313,8 +319,14 @@ page_fault(
|
|||||||
|
|
||||||
kprintf("\033[1;37;41m");
|
kprintf("\033[1;37;41m");
|
||||||
kprintf("Segmentation fault. (p:%d,rw:%d,user:%d,res:%d,id:%d) at 0x%x eip:0x%x pid=%d\n", present, rw, user, reserved, id, faulting_address, r->eip, getpid());
|
kprintf("Segmentation fault. (p:%d,rw:%d,user:%d,res:%d,id:%d) at 0x%x eip:0x%x pid=%d\n", present, rw, user, reserved, id, faulting_address, r->eip, getpid());
|
||||||
|
|
||||||
HALT_AND_CATCH_FIRE("Segmentation fault", r);
|
HALT_AND_CATCH_FIRE("Segmentation fault", r);
|
||||||
|
#else
|
||||||
|
signal_t * sig = malloc(sizeof(signal_t));
|
||||||
|
sig->handler = current_process->signals.functions[SIGSEGV];
|
||||||
|
sig->signum = SIGSEGV;
|
||||||
|
handle_signal(current_process, sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -98,7 +98,7 @@ exec(
|
|||||||
free(header);
|
free(header);
|
||||||
close_fs(file);
|
close_fs(file);
|
||||||
|
|
||||||
for (uintptr_t stack_pointer = 0x10000000; stack_pointer < 0x100F0000; stack_pointer += 0x1000) {
|
for (uintptr_t stack_pointer = 0x10000000; stack_pointer < 0x10100000; stack_pointer += 0x1000) {
|
||||||
alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
|
alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +120,8 @@ exec(
|
|||||||
process_append_fd((process_t *)current_process, NULL);
|
process_append_fd((process_t *)current_process, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_process->image.start = entry;
|
||||||
|
|
||||||
/* Go go go */
|
/* Go go go */
|
||||||
enter_user_jmp(entry, argc, argv_, 0x100EFFFF);
|
enter_user_jmp(entry, argc, argv_, 0x100EFFFF);
|
||||||
|
|
||||||
@ -150,6 +152,7 @@ system(
|
|||||||
* not all that much we can do right now. */
|
* not all that much we can do right now. */
|
||||||
while (child_task->finished == 0) {
|
while (child_task->finished == 0) {
|
||||||
if (child_task->finished != 0) break;
|
if (child_task->finished != 0) break;
|
||||||
|
switch_task(1);
|
||||||
}
|
}
|
||||||
/* Grab the child's return value */
|
/* Grab the child's return value */
|
||||||
int ret = child_task->status;
|
int ret = child_task->status;
|
||||||
|
@ -176,6 +176,7 @@ process_t * spawn_init() {
|
|||||||
init->finished = 0;
|
init->finished = 0;
|
||||||
init->wait_queue = list_create();
|
init->wait_queue = list_create();
|
||||||
init->shm_mappings = NULL;
|
init->shm_mappings = NULL;
|
||||||
|
init->signal_queue = list_create();
|
||||||
|
|
||||||
/* What the hey, let's also set the description on this one */
|
/* What the hey, let's also set the description on this one */
|
||||||
init->description = "[init]";
|
init->description = "[init]";
|
||||||
@ -261,8 +262,10 @@ process_t * spawn_process(volatile process_t * parent) {
|
|||||||
/* Zero out the process status */
|
/* Zero out the process status */
|
||||||
proc->status = 0;
|
proc->status = 0;
|
||||||
proc->finished = 0;
|
proc->finished = 0;
|
||||||
|
memset(proc->signals.functions, 0x00, sizeof(uintptr_t) * NUMSIGNALS);
|
||||||
proc->wait_queue = list_create();
|
proc->wait_queue = list_create();
|
||||||
proc->shm_mappings = list_create();
|
proc->shm_mappings = list_create();
|
||||||
|
proc->signal_queue = list_create();
|
||||||
|
|
||||||
/* Insert the process into the process tree as a child
|
/* Insert the process into the process tree as a child
|
||||||
* of the parent process. */
|
* of the parent process. */
|
||||||
@ -402,7 +405,9 @@ int wakeup_queue(list_t * queue) {
|
|||||||
int awoken_processes = 0;
|
int awoken_processes = 0;
|
||||||
while (queue->length > 0) {
|
while (queue->length > 0) {
|
||||||
node_t * node = list_pop(queue);
|
node_t * node = list_pop(queue);
|
||||||
make_process_ready(node->value);
|
if (!((process_t *)node->value)->finished) {
|
||||||
|
make_process_ready(node->value);
|
||||||
|
}
|
||||||
free(node);
|
free(node);
|
||||||
awoken_processes++;
|
awoken_processes++;
|
||||||
}
|
}
|
||||||
@ -414,3 +419,12 @@ int sleep_on(list_t * queue) {
|
|||||||
switch_task(0);
|
switch_task(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int XXX_slow_process_is_queued(process_t * proc) {
|
||||||
|
foreach(node, process_queue) {
|
||||||
|
if (node->value == proc)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
84
kernel/sys/signal.c
Normal file
84
kernel/sys/signal.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
|
*
|
||||||
|
* Signal Handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <system.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
void enter_signal_handler(uintptr_t location, int signum, uintptr_t stack) {
|
||||||
|
kprintf("[debug] Jumping to 0x%x with %d pushed and a stack at 0x%x\n", location, signum, stack);
|
||||||
|
asm volatile(
|
||||||
|
"mov %2, %%esp\n"
|
||||||
|
"pushl %1\n" /* argument count */
|
||||||
|
"pushl $0xFFFFFFFF\n"
|
||||||
|
"mov $0x23, %%ax\n" /* Segment selector */
|
||||||
|
"mov %%ax, %%ds\n"
|
||||||
|
"mov %%ax, %%es\n"
|
||||||
|
"mov %%ax, %%fs\n"
|
||||||
|
"mov %%ax, %%gs\n"
|
||||||
|
"mov %%esp, %%eax\n" /* Stack -> EAX */
|
||||||
|
"pushl $0x23\n" /* Segment selector again */
|
||||||
|
"pushl %%eax\n"
|
||||||
|
"pushf\n" /* Push flags */
|
||||||
|
"popl %%eax\n" /* Fix the Interrupt flag */
|
||||||
|
"orl $0x200, %%eax\n"
|
||||||
|
"pushl %%eax\n"
|
||||||
|
"pushl $0x1B\n"
|
||||||
|
"pushl %0\n" /* Push the entry point */
|
||||||
|
"iret\n"
|
||||||
|
: : "m"(location), "m"(signum), "r"(stack) : "%ax", "%esp", "%eax");
|
||||||
|
kprintf("Yep, definitely an iret issue.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_signal(process_t * proc, signal_t * sig) {
|
||||||
|
kprintf("[signal] Need to process signal %d for process %d\n", sig->signum, proc->id);
|
||||||
|
|
||||||
|
if (!sig->handler) {
|
||||||
|
kprintf("[debug] Process %d killed by unhandled signal.\n", proc->id);
|
||||||
|
kprintf("Current process = %d\n", current_process->id);
|
||||||
|
kexit(127 + sig);
|
||||||
|
kprintf("Still here.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sig->handler == 1) /* Ignore */ {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t stack = 0x100EFFFF;
|
||||||
|
|
||||||
|
/* Not marked as ignored, must call signal */
|
||||||
|
enter_signal_handler(sig->handler, sig->signum, stack);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
list_t * rets_from_sig;
|
||||||
|
|
||||||
|
void return_from_signal_handler() {
|
||||||
|
kprintf("[debug] Return From Signal for process %d\n", current_process->id);
|
||||||
|
|
||||||
|
if (__builtin_expect(!rets_from_sig, 0)) {
|
||||||
|
rets_from_sig = list_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
list_insert(rets_from_sig, current_process);
|
||||||
|
|
||||||
|
switch_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fix_signal_stacks() {
|
||||||
|
if (rets_from_sig) {
|
||||||
|
while (rets_from_sig->head) {
|
||||||
|
node_t * n = list_dequeue(rets_from_sig);
|
||||||
|
process_t * p = n->value;
|
||||||
|
p->thread.esp = p->signal_state.esp;
|
||||||
|
p->thread.eip = p->signal_state.eip;
|
||||||
|
p->thread.ebp = p->signal_state.ebp;
|
||||||
|
memcpy(p->image.stack - KERNEL_STACK_SIZE, p->signal_kstack, KERNEL_STACK_SIZE);
|
||||||
|
free(p->signal_kstack);
|
||||||
|
make_process_ready(p);
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -110,7 +110,6 @@ static int wait(int child) {
|
|||||||
kprintf("Tried to wait for non-existent process\n");
|
kprintf("Tried to wait for non-existent process\n");
|
||||||
}
|
}
|
||||||
while (child_task->finished == 0) {
|
while (child_task->finished == 0) {
|
||||||
if (child_task->finished != 0) break;
|
|
||||||
/* Add us to the wait queue for this child */
|
/* Add us to the wait queue for this child */
|
||||||
sleep_on(child_task->wait_queue);
|
sleep_on(child_task->wait_queue);
|
||||||
}
|
}
|
||||||
@ -313,6 +312,55 @@ static int kernel_name_XXX(char * buffer) {
|
|||||||
__kernel_arch);
|
__kernel_arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int send_signal(pid_t process, uint32_t signal) {
|
||||||
|
process_t * receiver = process_from_pid(process);
|
||||||
|
|
||||||
|
if (!receiver) {
|
||||||
|
/* Invalid pid */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receiver->user != current_process->user && current_process->user != USER_ROOT_UID) {
|
||||||
|
/* No way in hell. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signal >= NUMSIGNALS) {
|
||||||
|
/* Invalid signal */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receiver->finished) {
|
||||||
|
/* Can't send signals to finished processes */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append signal to list */
|
||||||
|
signal_t * sig = malloc(sizeof(signal_t));
|
||||||
|
sig->handler = (uintptr_t)receiver->signals.functions[signal];
|
||||||
|
sig->signum = signal;
|
||||||
|
memset(&sig->registers_before, 0x00, sizeof(regs_t));
|
||||||
|
|
||||||
|
if (!XXX_slow_process_is_queued(receiver)) {
|
||||||
|
make_process_ready(receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("[signal] Sending signal %d to PID %d from PID %d\n", signal, process, current_process->id);
|
||||||
|
|
||||||
|
list_insert(receiver->signal_queue, sig);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uintptr_t sys_signal(uint32_t signum, uintptr_t handler) {
|
||||||
|
if (signum >= NUMSIGNALS) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uintptr_t old = current_process->signals.functions[signum];
|
||||||
|
current_process->signals.functions[signum] = handler;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static void inspect_memory (uintptr_t vaddr) {
|
static void inspect_memory (uintptr_t vaddr) {
|
||||||
// Please use this scary hack of a function as infrequently as possible.
|
// Please use this scary hack of a function as infrequently as possible.
|
||||||
@ -322,10 +370,10 @@ static void inspect_memory (uintptr_t vaddr) {
|
|||||||
|
|
||||||
static int reboot() {
|
static int reboot() {
|
||||||
kprintf("[kernel] Reboot requested from process %d by user #%d\n", current_process->id, current_process->user);
|
kprintf("[kernel] Reboot requested from process %d by user #%d\n", current_process->id, current_process->user);
|
||||||
kprintf("[kernel] Good bye!\n");
|
if (current_process->user != USER_ROOT_UID) {
|
||||||
if (current_process->user != 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
kprintf("[kernel] Good bye!\n");
|
||||||
/* Goodbye, cruel world */
|
/* Goodbye, cruel world */
|
||||||
uint8_t out = 0x02;
|
uint8_t out = 0x02;
|
||||||
while ((out & 0x02) != 0) {
|
while ((out & 0x02) != 0) {
|
||||||
@ -435,7 +483,9 @@ static uintptr_t syscalls[] = {
|
|||||||
(uintptr_t)&mousedevice,
|
(uintptr_t)&mousedevice,
|
||||||
(uintptr_t)&sys_mkdir,
|
(uintptr_t)&sys_mkdir,
|
||||||
(uintptr_t)&shm_obtain,
|
(uintptr_t)&shm_obtain,
|
||||||
(uintptr_t)&shm_release, /* 36 */
|
(uintptr_t)&shm_release, /* 36 */
|
||||||
|
(uintptr_t)&send_signal,
|
||||||
|
(uintptr_t)&sys_signal,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
uint32_t num_syscalls;
|
uint32_t num_syscalls;
|
||||||
|
@ -76,11 +76,14 @@ void free_directory(page_directory_t * dir) {
|
|||||||
void reap_process(process_t * proc) {
|
void reap_process(process_t * proc) {
|
||||||
list_free(proc->wait_queue);
|
list_free(proc->wait_queue);
|
||||||
free(proc->wait_queue);
|
free(proc->wait_queue);
|
||||||
|
list_free(proc->signal_queue);
|
||||||
|
free(proc->signal_queue);
|
||||||
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
|
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
|
||||||
free_directory(proc->thread.page_directory);
|
free_directory(proc->thread.page_directory);
|
||||||
free((void *)(proc->fds.entries));
|
free((void *)(proc->fds.entries));
|
||||||
|
|
||||||
shm_release_all(proc);
|
shm_release_all(proc);
|
||||||
kprintf("reaping %s\n", proc->name);
|
kprintf("[kernel] reaping %s\n", proc->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -322,6 +325,17 @@ switch_task(uint8_t reschedule) {
|
|||||||
reap_process(proc);
|
reap_process(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fix_signal_stacks();
|
||||||
|
/* XXX: Signals */
|
||||||
|
if (!current_process->finished) {
|
||||||
|
if (current_process->signal_queue->length > 0) {
|
||||||
|
node_t * node = list_dequeue(current_process->signal_queue);
|
||||||
|
signal_t * sig = node->value;
|
||||||
|
free(node);
|
||||||
|
handle_signal(current_process, sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,6 +371,16 @@ switch_next() {
|
|||||||
/* Validate */
|
/* Validate */
|
||||||
assert((eip > (uintptr_t)&code) && (eip < (uintptr_t)&end) && "Task switch return point is not within Kernel!");
|
assert((eip > (uintptr_t)&code) && (eip < (uintptr_t)&end) && "Task switch return point is not within Kernel!");
|
||||||
|
|
||||||
|
if (!current_process->finished) {
|
||||||
|
if (current_process->signal_queue->length > 0) {
|
||||||
|
current_process->signal_kstack = malloc(KERNEL_STACK_SIZE);
|
||||||
|
current_process->signal_state.esp = current_process->thread.esp;
|
||||||
|
current_process->signal_state.eip = current_process->thread.eip;
|
||||||
|
current_process->signal_state.ebp = current_process->thread.ebp;
|
||||||
|
memcpy(current_process->signal_kstack, current_process->image.stack - KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the page directory */
|
/* Set the page directory */
|
||||||
current_directory = current_process->thread.page_directory;
|
current_directory = current_process->thread.page_directory;
|
||||||
/* Set the kernel stack in the TSS */
|
/* Set the kernel stack in the TSS */
|
||||||
|
@ -18,6 +18,9 @@ DEFN_SYSCALL1(chdir, 28, char *);
|
|||||||
DEFN_SYSCALL0(getuid, 23);
|
DEFN_SYSCALL0(getuid, 23);
|
||||||
DEFN_SYSCALL0(gethostname, 32);
|
DEFN_SYSCALL0(gethostname, 32);
|
||||||
|
|
||||||
|
DEFN_SYSCALL2(signal, 38, uint32_t, void *);
|
||||||
|
DEFN_SYSCALL2(send_signal, 37, uint32_t, uint32_t)
|
||||||
|
|
||||||
#define LINE_LEN 4096
|
#define LINE_LEN 4096
|
||||||
|
|
||||||
char cwd[1024] = {'/',0};
|
char cwd[1024] = {'/',0};
|
||||||
@ -79,12 +82,24 @@ void draw_prompt(int ret) {
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t child = 0;
|
||||||
|
|
||||||
|
void sig_int(int sig) {
|
||||||
|
if (child) {
|
||||||
|
syscall_send_signal(child, sig);
|
||||||
|
} else {
|
||||||
|
printf("stop that!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
int pid = getpid();
|
int pid = getpid();
|
||||||
int nowait = 0;
|
int nowait = 0;
|
||||||
int free_cmd = 0;
|
int free_cmd = 0;
|
||||||
int last_ret = 0;
|
int last_ret = 0;
|
||||||
|
|
||||||
|
syscall_signal(9, sig_int);
|
||||||
|
|
||||||
getusername();
|
getusername();
|
||||||
gethostname();
|
gethostname();
|
||||||
|
|
||||||
@ -168,6 +183,7 @@ int main(int argc, char ** argv) {
|
|||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
if (!nowait) {
|
if (!nowait) {
|
||||||
|
child = f;
|
||||||
last_ret = syscall_wait(f);
|
last_ret = syscall_wait(f);
|
||||||
}
|
}
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
@ -18,6 +18,25 @@ DEFN_SYSCALL1(setuid, 24, unsigned int);
|
|||||||
DEFN_SYSCALL1(kernel_string_XXX, 25, char *);
|
DEFN_SYSCALL1(kernel_string_XXX, 25, char *);
|
||||||
DEFN_SYSCALL0(gethostname, 32);
|
DEFN_SYSCALL0(gethostname, 32);
|
||||||
|
|
||||||
|
DEFN_SYSCALL2(signal, 38, uint32_t, void *);
|
||||||
|
DEFN_SYSCALL2(send_signal, 37, uint32_t, uint32_t)
|
||||||
|
|
||||||
|
uint32_t child = 0;
|
||||||
|
|
||||||
|
void sig_int(int sig) {
|
||||||
|
/* Pass onto the shell */
|
||||||
|
if (child) {
|
||||||
|
syscall_send_signal(child, sig);
|
||||||
|
}
|
||||||
|
/* Else, ignore */
|
||||||
|
}
|
||||||
|
|
||||||
|
void sig_segv(int sig) {
|
||||||
|
printf("Segmentation fault.\n");
|
||||||
|
exit(127 + sig);
|
||||||
|
/* no return */
|
||||||
|
}
|
||||||
|
|
||||||
int checkUserPass(char * user, char * pass) {
|
int checkUserPass(char * user, char * pass) {
|
||||||
|
|
||||||
/* Generate SHA512 */
|
/* Generate SHA512 */
|
||||||
@ -62,6 +81,9 @@ int main(int argc, char ** argv) {
|
|||||||
|
|
||||||
fprintf(stdout, "\n%s\n\n", _uname);
|
fprintf(stdout, "\n%s\n\n", _uname);
|
||||||
|
|
||||||
|
syscall_signal(9, sig_int);
|
||||||
|
syscall_signal(11, sig_segv);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
char * username = malloc(sizeof(char) * 1024);
|
char * username = malloc(sizeof(char) * 1024);
|
||||||
char * password = malloc(sizeof(char) * 1024);
|
char * password = malloc(sizeof(char) * 1024);
|
||||||
@ -100,8 +122,10 @@ int main(int argc, char ** argv) {
|
|||||||
syscall_setuid(uid);
|
syscall_setuid(uid);
|
||||||
int i = execve(args[0], args, NULL);
|
int i = execve(args[0], args, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
child = f;
|
||||||
syscall_wait(f);
|
syscall_wait(f);
|
||||||
}
|
}
|
||||||
|
child = 0;
|
||||||
free(username);
|
free(username);
|
||||||
free(password);
|
free(password);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
|
*
|
||||||
* Terminal Emulator
|
* Terminal Emulator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2822,6 +2823,10 @@ void clear_input() {
|
|||||||
input_collected = 0;
|
input_collected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t child_pid = 0;
|
||||||
|
|
||||||
|
DEFN_SYSCALL2(send_signal, 37, uint32_t, uint32_t)
|
||||||
|
|
||||||
int buffer_put(char c) {
|
int buffer_put(char c) {
|
||||||
if (c == 8) {
|
if (c == 8) {
|
||||||
/* Backspace */
|
/* Backspace */
|
||||||
@ -2834,6 +2839,10 @@ int buffer_put(char c) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (c == 3) {
|
||||||
|
syscall_send_signal(child_pid, 9);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (c < 10 || (c > 10 && c < 32) || c > 126) {
|
if (c < 10 || (c > 10 && c < 32) || c > 126) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2978,6 +2987,10 @@ int main(int argc, char ** argv) {
|
|||||||
int i = execve(tokens[0], tokens, NULL);
|
int i = execve(tokens[0], tokens, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
child_pid = f;
|
||||||
|
printf("[terminal] child is %d\n", child_pid);
|
||||||
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
while (1) {
|
while (1) {
|
||||||
struct stat _stat;
|
struct stat _stat;
|
||||||
|
Loading…
Reference in New Issue
Block a user