summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--cpu/idt.c134
-rw-r--r--cpu/syscall.c7
-rw-r--r--includes/signal.h46
-rw-r--r--sched/scheduler.c65
-rw-r--r--sched/scheduler.h12
-rw-r--r--userland/libc/Makefile2
-rw-r--r--userland/libc/include/signal.h45
-rw-r--r--userland/libc/include/syscall.h2
-rw-r--r--userland/libc/signal/kill.c4
-rw-r--r--userland/libc/signal/sigaction.c7
11 files changed, 205 insertions, 121 deletions
diff --git a/Makefile b/Makefile
index 0218376..d106a75 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC="./sysroot/bin/i686-sb-gcc"
AS="./sysroot/bin/i686-sb-as"
-OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o scalls/recvfrom.o math.o scalls/sendto.o
+OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o scalls/recvfrom.o math.o scalls/sendto.o signal.o scalls/kill.o scalls/sigaction.o
CFLAGS = -O2 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I.
INCLUDE=-I./includes/ -I./libc/include/
diff --git a/cpu/idt.c b/cpu/idt.c
index 1a8c95e..abcafad 100644
--- a/cpu/idt.c
+++ b/cpu/idt.c
@@ -53,9 +53,7 @@ __attribute__((no_caller_saved_registers)) void EOI(uint8_t irq) {
outb(MASTER_PIC_COMMAND_PORT, 0x20);
}
-__attribute__((interrupt)) void
-kernel_general_protection_fault(kernel_registers_t *regs) {
- asm("cli");
+__attribute__((interrupt)) void general_protection_fault(registers_t *regs) {
klog("General Protetion Fault", 0x1);
kprintf(" Error Code: %x\n", regs->error_code);
kprintf("Instruction Pointer: %x\n", regs->eip);
@@ -66,119 +64,48 @@ kernel_general_protection_fault(kernel_registers_t *regs) {
EOI(0xD - 8);
}
-__attribute__((interrupt)) void general_protection_fault(registers_t *regs) {
- kprintf("\n");
- klog("KERNEL General Protetion Fault", 0x1);
- kprintf(" Error Code: %x\n", regs->error_code);
-#define EXTERNAL_TO_PROCESSOR (1 << 0)
-
-#define WAS(_b) if (regs->error_code & (_b))
- if (0 == regs->error_code) {
- kprintf("This exception is not segment related.");
- } else {
- WAS(EXTERNAL_TO_PROCESSOR) {
- kprintf("Exception originated externally to the processor.");
- }
- kprintf("Index references: ");
- switch ((regs->error_code >> 1) & 0x3) {
- case 0:
- kprintf("GDT");
- break;
- case 3:
- case 1:
- kprintf("IDT");
- break;
- case 2:
- kprintf("LDT");
- break;
- }
- kprintf("\n");
- kprintf("Segmenet index: %x\n", regs->error_code >> 15);
- }
- /* kprintf(" Page protection violation: %x\n", regs->error_code & 0x1);
- kprintf(" Write access: %x\n", (regs->error_code & (0x1<<1)) >> 1);
- kprintf(" No privilege violation: %x\n", (regs->error_code & (0x1<<2))
- >> 2); kprintf(" Instruction fetch: %x\n", (regs->error_code & (0x1<<4)) >>
- 4); kprintf(" Shadow stack access: %x\n", (regs->error_code & (0x1<<6)) >>
- 6);*/
- kprintf("Instruction Pointer: %x\n", regs->eip);
- asm("hlt");
- EOI(0xD - 8);
-}
-
__attribute__((interrupt)) void double_fault(registers_t *regs) {
(void)regs;
- klog("DOUBLE FAULT, THIS IS REALLY BAD", LOG_ERROR);
- asm("cli");
+ klog("DOUBLE FAULT", LOG_ERROR);
asm("hlt");
for (;;)
;
}
__attribute__((interrupt)) void page_fault(registers_t *regs) {
- asm("cli");
- klog("Page Fault", LOG_ERROR);
- if (get_current_task()) {
- kprintf(" PID: %x\n", get_current_task()->pid);
- kprintf(" Name: %s\n", get_current_task()->program_name);
+ if (0xFFFFDEAD == regs->eip) {
+ asm("sti");
+ for (;;)
+ switch_task();
}
- kprintf(" Error Code: %x\n", regs->error_code);
- kprintf(" Interrupt Number: %x\n", regs->interrupt_number);
- kprintf(" Instruction Pointer: %x\n", regs->eip);
- dump_backtrace(14);
- asm("hlt");
- for (;;)
- ;
-}
-
-/*
-__attribute__((interrupt)) void page_fault(registers_t *regs) {
- asm("cli");
klog("Page Fault", LOG_ERROR);
if (get_current_task()) {
- kprintf(" PID: %x\n", get_current_task()->pid);
- kprintf(" Name: %s\n", get_current_task()->program_name);
- }
- kprintf(" Error Code: %x\n", regs->error_code);
- kprintf(" Interrupt Number: %x\n", regs->interrupt_number);
-#define PAGE_PRESENT (1 << 0)
-#define WRITE_ATTEMPT (1 << 1)
-#define USER_LEVEL (1 << 2)
-#define RESERVED_WRITE (1 << 3)
-#define INSTRUCTION_FETCH (1 << 4)
-#define PROTECTION_KEY_VIOLATION (1 << 5)
-#define SHADOW_STACK_ACCESS (1 << 6)
-
-#define WAS(_b) if (regs->error_code & (_b))
-
- WAS(PAGE_PRESENT) { kprintf(" Page was present.\n"); }
- else {
- kprintf(" Page is not present.\n");
+ kprintf("PID: %x\n", get_current_task()->pid);
+ kprintf("Name: %s\n", get_current_task()->program_name);
}
+ kprintf("Error Code: %x\n", regs->error_code);
+ kprintf("Instruction Pointer: %x\n", regs->eip);
- WAS(WRITE_ATTEMPT) { kprintf(" Write attempt.\n"); }
- else {
- kprintf(" Read attempt.\n");
- }
+ if (regs->error_code & (1 << 0))
+ kprintf("page-protection violation\n");
+ else
+ kprintf("non-present page\n");
- WAS(USER_LEVEL) {
- get_current_task()->dead = 1;
- kprintf(" Page fault in ring 3.\n");
- }
- else {
- kprintf(" Page fault in ring 0-2.\n");
- }
+ if (regs->error_code & (1 << 1))
+ kprintf("write access\n");
+ else
+ kprintf("read access\n");
- WAS(INSTRUCTION_FETCH) { kprintf(" Attempted instruction fetch.\n"); }
+ if (regs->error_code & (1 << 2))
+ kprintf("CPL = 3\n");
- WAS(SHADOW_STACK_ACCESS) { kprintf(" Attempted shadow stack access.\n"); }
+ if (regs->error_code & (1 << 4))
+ kprintf("Attempted instruction fetch\n");
- kprintf(" Instruction Pointer: %x\n", regs->eip);
- dump_backtrace(12);
+ dump_backtrace(5);
asm("hlt");
for (;;)
;
- EOI(0xE - 8);
-}*/
+}
static inline void io_wait(void) { outb(0x80, 0); }
@@ -252,22 +179,15 @@ void IRQ_clear_mask(unsigned char IRQline) {
}
void idt_init(void) {
- install_handler(page_fault, INT_32_TRAP_GATE(0x3), 0xE);
- install_handler(double_fault, INT_32_TRAP_GATE(0x0), 0x8);
- install_handler(kernel_general_protection_fault, INT_32_TRAP_GATE(0x0), 0xD);
+ install_handler(page_fault, INT_32_INTERRUPT_GATE(0x0), 0xE);
+ install_handler(double_fault, INT_32_INTERRUPT_GATE(0x0), 0x8);
+ install_handler(general_protection_fault, INT_32_INTERRUPT_GATE(0x0), 0xD);
PIC_remap(0x20);
IRQ_clear_mask(0xb);
IRQ_set_mask(0xe);
IRQ_set_mask(0xf);
IRQ_clear_mask(2);
- /*
- IRQ_set_mask(0xe);
- IRQ_set_mask(2);
- IRQ_set_mask(1);
- IRQ_set_mask(0);
- IRQ_clear_mask(0x5);
- IRQ_clear_mask(0xB);*/
idtr.interrupt_table = (struct IDT_Descriptor **)&IDT_Entry;
idtr.size = (sizeof(struct IDT_Descriptor) * IDT_MAX_ENTRY) - 1;
diff --git a/cpu/syscall.c b/cpu/syscall.c
index 9bf5075..4978732 100644
--- a/cpu/syscall.c
+++ b/cpu/syscall.c
@@ -10,6 +10,7 @@
#include <scalls/accept.h>
#include <scalls/bind.h>
#include <scalls/ftruncate.h>
+#include <scalls/kill.h>
#include <scalls/mkdir.h>
#include <scalls/mmap.h>
#include <scalls/msleep.h>
@@ -20,6 +21,7 @@
#include <scalls/socket.h>
#include <scalls/stat.h>
#include <scalls/uptime.h>
+#include <scalls/sigaction.h>
#include <stdint.h>
#include <string.h>
@@ -124,7 +126,7 @@ void *align_page(void *a);
int syscall_brk(void *addr) {
void *end = get_current_task()->data_segment_end;
- if (!mmu_allocate_region(end, addr - end, MMU_FLAG_RW))
+ if (!mmu_allocate_region(end, addr - end, MMU_FLAG_RW, NULL))
return -ENOMEM;
get_current_task()->data_segment_end = align_page(addr);
return 0;
@@ -164,7 +166,8 @@ void (*syscall_functions[])() = {
(void(*))syscall_ftruncate, (void(*))syscall_stat,
(void(*))syscall_msleep, (void(*))syscall_uptime,
(void(*))syscall_mkdir, (void(*))syscall_recvfrom,
- (void(*))syscall_sendto,
+ (void(*))syscall_sendto, (void(*))syscall_kill,
+ (void(*))syscall_sigaction,
};
void syscall_function_handler(uint32_t eax, uint32_t arg1, uint32_t arg2,
diff --git a/includes/signal.h b/includes/signal.h
new file mode 100644
index 0000000..3de9998
--- /dev/null
+++ b/includes/signal.h
@@ -0,0 +1,46 @@
+#ifndef SIGNAL_H
+#define SIGNAL_H
+#include <sys/types.h>
+#define SIGHUP 0
+#define SIGINT 1
+#define SIGWINCH 2
+#define SIGQUIT 3
+#define SIG_IGN 4
+typedef int pid_t;
+typedef int uid_t;
+typedef int sigset_t;
+
+union sigval {
+ int sival_int; // Integer signal value.
+ void *sival_ptr; // Pointer signal value.
+};
+
+struct siginfo {
+ int si_signo; // Signal number.
+ int si_code; // Signal code.
+ int si_errno; // If non-zero, an errno value associated with
+ // this signal, as described in <errno.h>.
+ pid_t si_pid; // Sending process ID.
+ uid_t si_uid; // Real user ID of sending process.
+ void *si_addr; // Address of faulting instruction.
+ int si_status; // Exit value or signal.
+ long si_band; // Band event for SIGPOLL.
+ union sigval si_value; // Signal value.
+};
+
+typedef struct siginfo siginfo_t;
+
+int kill(pid_t pid, int sig);
+
+struct sigaction {
+ void (*sa_handler)(int); // Pointer to a signal-catching function or one of
+ // the macros SIG_IGN or SIG_DFL.
+ sigset_t sa_mask; // Additional set of signals to be blocked during execution
+ // of signal-catching function.
+ int sa_flags; // Special flags to affect behavior of signal.
+ void (*sa_sigaction)(int, siginfo_t *,
+ void *); // Pointer to a signal-catching function.
+};
+
+int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
+#endif // SIGNAL_H
diff --git a/sched/scheduler.c b/sched/scheduler.c
index ed85f9b..a6ace7d 100644
--- a/sched/scheduler.c
+++ b/sched/scheduler.c
@@ -19,6 +19,14 @@ extern uint32_t read_eip(void);
process_t *get_current_task(void) { return current_task; }
+void set_signal_handler(int sig, void (*handler)(int)) {
+ if (sig >= 20 || sig < 0)
+ return;
+ if (9 == sig)
+ return;
+ current_task->signal_handlers[sig] = handler;
+}
+
process_t *create_process(process_t *p) {
process_t *r;
r = ksbrk(sizeof(process_t));
@@ -37,9 +45,15 @@ process_t *create_process(process_t *p) {
r->cr3 = (p) ? clone_directory(get_active_pagedirectory())
: get_active_pagedirectory();
r->next = 0;
+ r->incoming_signal = 0;
r->parent = p;
r->child = NULL;
r->halt_list = NULL;
+
+ mmu_allocate_region((void *)(0x80000000 - 0x1000), 0x1000, MMU_FLAG_RW,
+ r->cr3);
+ r->signal_handler_stack = 0x80000000;
+
strcpy(r->current_working_directory, "/");
r->data_segment_end = (p) ? p->data_segment_end : NULL;
memset((void *)r->halts, 0, 2 * sizeof(uint32_t));
@@ -50,6 +64,8 @@ process_t *create_process(process_t *p) {
r->file_descriptors[i]->reference_count++;
}
}
+ if (i < 20)
+ r->signal_handlers[i] = NULL;
r->read_halt_inode[i] = NULL;
r->write_halt_inode[i] = NULL;
r->disconnect_halt_inode[i] = NULL;
@@ -132,7 +148,8 @@ void exit(int status) {
}
uint32_t setup_stack(uint32_t stack_pointer, int argc, char **argv) {
- mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW);
+ mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW,
+ NULL);
flush_tlb();
uint32_t ptr = stack_pointer;
@@ -244,6 +261,8 @@ process_t *next_task(process_t *c) {
c = c->next;
if (!c)
c = ready_queue;
+ if (c->incoming_signal)
+ break;
if (c->sleep_until > pit_num_ms())
continue;
if (is_halted(c) || c->dead)
@@ -271,6 +290,25 @@ int task_save_state(void) {
return 1;
}
+int kill(pid_t pid, int sig) {
+ process_t *p = current_task;
+ p = p->next;
+ if (!p)
+ p = ready_queue;
+ for (; p->pid != pid;) {
+ if (p == current_task)
+ break;
+ p = p->next;
+ if (!p)
+ p = ready_queue;
+ }
+ if (p->pid != pid)
+ return -ESRCH;
+ p->incoming_signal = sig;
+ return 0;
+}
+
+void jump_signal_handler(void *func, uint32_t esp);
void switch_task() {
if (!current_task)
return;
@@ -283,15 +321,32 @@ void switch_task() {
active_directory = current_task->cr3;
- asm(" \
+ if (current_task->incoming_signal) {
+ uint8_t sig = current_task->incoming_signal;
+ current_task->incoming_signal = 0;
+ asm("mov %0, %%cr3" ::"r"(current_task->cr3->physical_address));
+
+ void *handler = current_task->signal_handlers[sig];
+ if (9 == sig) {
+ klog("Task recieved SIGKILL", LOG_NOTE);
+ exit(0);
+ }
+ if (!handler) {
+ klog("Task recieved unhandeled signal. Killing process.", LOG_WARN);
+ exit(1);
+ }
+ jump_signal_handler(handler, current_task->signal_handler_stack);
+ } else {
+ asm(" \
mov %0, %%esp; \
mov %1, %%ebp; \
mov %2, %%ecx; \
mov %3, %%cr3; \
mov $0x1, %%eax; \
jmp *%%ecx" ::"r"(current_task->esp),
- "r"(current_task->ebp), "r"(current_task->eip),
- "r"(current_task->cr3->physical_address));
+ "r"(current_task->ebp), "r"(current_task->eip),
+ "r"(current_task->cr3->physical_address));
+ }
}
MemoryMap **get_free_map(void) {
@@ -318,7 +373,7 @@ void *allocate_virtual_user_memory(size_t length, int prot, int flags) {
if ((void *)-1 == rc)
return (void *)-1;
- mmu_allocate_region(rc, length, MMU_FLAG_RW);
+ mmu_allocate_region(rc, length, MMU_FLAG_RW, NULL);
return rc;
}
diff --git a/sched/scheduler.h b/sched/scheduler.h
index 7df7c40..fc92ff3 100644
--- a/sched/scheduler.h
+++ b/sched/scheduler.h
@@ -4,6 +4,7 @@
#include <fs/vfs.h>
#include <halts.h>
#include <mmu.h>
+#include <signal.h>
#define MAX_PATH 256
#define KEYBOARD_HALT 0
@@ -19,6 +20,8 @@ void *mmap(void *addr, size_t length, int prot, int flags, int fd,
size_t offset);
int munmap(void *addr, size_t length);
int msync(void *addr, size_t length, int flags);
+int kill(pid_t pid, int sig);
+void set_signal_handler(int sig, void (*handler)(int));
typedef struct {
void *u_address;
@@ -34,25 +37,26 @@ struct Process {
char program_name[100];
char current_working_directory[MAX_PATH];
uint32_t eip, esp, ebp;
+ uint8_t incoming_signal;
+ uint32_t signal_handler_stack;
+ void *signal_handlers[20];
PageDirectory *cr3;
vfs_fd_t *file_descriptors[100];
vfs_inode_t *read_halt_inode[100];
vfs_inode_t *write_halt_inode[100];
vfs_inode_t *disconnect_halt_inode[100];
- // struct vfs_fd_t ** file_descriptors;
uint32_t halts[2];
struct Halt *halt_list;
void *data_segment_end;
- // uint32_t *halts;
process_t *next;
process_t *parent;
+ // TODO: Create a linkedlist of childs so that the parent process
+ // can do stuff such as reap zombies and get status.
process_t *child;
MemoryMap *maps[100];
uint32_t sleep_until;
int child_rc;
int dead;
- // FIXME: Create a linkedlisti of childs so that the parent process
- // can do stuff such as reap zombies and get status.
};
process_t *get_current_task(void);
diff --git a/userland/libc/Makefile b/userland/libc/Makefile
index bcb82f8..c755b94 100644
--- a/userland/libc/Makefile
+++ b/userland/libc/Makefile
@@ -2,7 +2,7 @@ CC="i686-sb-gcc"
AR="i686-sb-ar"
AS="i686-sb-as"
CFLAGS = -ggdb -ffreestanding -O2 -Wall -pedantic -Wimplicit-fallthrough -I./include/ -static
-OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o sys/socket/recvfrom.o sys/socket/sendto.o
+OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o sys/socket/recvfrom.o sys/socket/sendto.o signal/kill.o signal/sigaction.o
all: libc.a
%.o: %.c
diff --git a/userland/libc/include/signal.h b/userland/libc/include/signal.h
index 2e6566d..621710b 100644
--- a/userland/libc/include/signal.h
+++ b/userland/libc/include/signal.h
@@ -1,9 +1,52 @@
#ifndef SIGNAL_H
#define SIGNAL_H
+#include <sys/types.h>
#define SIGHUP 0
#define SIGINT 1
#define SIGWINCH 2
#define SIGQUIT 3
#define SIG_IGN 4
-typedef int sig_atomic_t;
+#define SIGSEGV 5
+#define SIGILL 6
+#define SIGABRT 7
+#define SIGBUS 8
+#define SIGKILL 9
+#define SIGFPE 10
+
+typedef int pid_t;
+typedef int sigset_t;
+
+union sigval {
+ int sival_int; // Integer signal value.
+ void *sival_ptr; // Pointer signal value.
+};
+
+struct siginfo {
+ int si_signo; // Signal number.
+ int si_code; // Signal code.
+ int si_errno; // If non-zero, an errno value associated with
+ // this signal, as described in <errno.h>.
+ pid_t si_pid; // Sending process ID.
+ uid_t si_uid; // Real user ID of sending process.
+ void *si_addr; // Address of faulting instruction.
+ int si_status; // Exit value or signal.
+ long si_band; // Band event for SIGPOL9
+ union sigval si_value; // Signal value.
+};
+
+typedef struct siginfo siginfo_t;
+
+int kill(pid_t pid, int sig);
+
+struct sigaction {
+ void (*sa_handler)(int); // Pointer to a signal-catching function or one of
+ // the macros SIG_IGN or SIG_DFL.
+ sigset_t sa_mask; // Additional set of signals to be blocked during execution
+ // of signal-catching function.
+ int sa_flags; // Special flags to affect behavior of signal.
+ void (*sa_sigaction)(int, siginfo_t *,
+ void *); // Pointer to a signal-catching function.
+};
+
+int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
#endif // SIGNAL_H
diff --git a/userland/libc/include/syscall.h b/userland/libc/include/syscall.h
index 3af425d..3faafbf 100644
--- a/userland/libc/include/syscall.h
+++ b/userland/libc/include/syscall.h
@@ -34,6 +34,8 @@
#define SYS_MKDIR 26
#define SYS_RECVFROM 27
#define SYS_SENDTO 28
+#define SYS_KILL 29
+#define SYS_SIGACTION 30
int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx,
uint32_t esi, uint32_t edi);
diff --git a/userland/libc/signal/kill.c b/userland/libc/signal/kill.c
new file mode 100644
index 0000000..3351baa
--- /dev/null
+++ b/userland/libc/signal/kill.c
@@ -0,0 +1,4 @@
+#include <signal.h>
+#include <syscall.h>
+
+int kill(pid_t pid, int sig) { RC_ERRNO(syscall(SYS_KILL, pid, sig, 0, 0, 0)) }
diff --git a/userland/libc/signal/sigaction.c b/userland/libc/signal/sigaction.c
new file mode 100644
index 0000000..1ff22a7
--- /dev/null
+++ b/userland/libc/signal/sigaction.c
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include <syscall.h>
+
+int sigaction(int sig, const struct sigaction *act,
+ struct sigaction *oact) {
+ RC_ERRNO(syscall(SYS_SIGACTION, sig, act, oact, 0,0))
+}