diff --git a/fs/exec.c b/fs/exec.c index f839b6752a527f2c9c1efb2da13106ef42edab3c..3b5427bd29c2f0eff59cd177ec52ee6beec9b4e2 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -201,6 +202,14 @@ int do_execve(unsigned long * eip,long tmp,char * filename, iput(current->executable); current->executable = inode; + current->signal = 0; + for (i=0 ; i<32 ; i++) { + current->sigaction[i].sa_mask = 0; + current->sigaction[i].sa_flags = 0; + if (current->sigaction[i].sa_handler != SIG_IGN) + current->sigaction[i].sa_handler = NULL; + } + for (i=0 ; iclose_on_exec>>i)&1) sys_close(i); diff --git a/include/linux/mm.h b/include/linux/mm.h index e7d2e6d15d5056338e18b1121f71d260d917d06d..4dc35da16d83f7b40b54b73a162762d73a92c628 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -6,6 +6,7 @@ #define PAGE_SIZE 4096 extern unsigned long get_free_page(); +extern unsigned long put_dirty_page(unsigned long page,unsigned long address); extern void free_page(unsigned long addr); extern inline void oom(); diff --git a/include/linux/sched.h b/include/linux/sched.h index 1791e7d524c1bf2c290c233f8b5b9737b657402d..8c08d6f07147a776faf695e2e7a8a36faaa9ca67 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -21,6 +21,7 @@ #include #include #include +#include #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 @@ -79,6 +80,9 @@ struct task_struct { long state; long counter; long priority; + long signal; + struct sigaction sigaction[32]; + long blocked; long pid; unsigned long start_code,end_code,end_data,brk,start_stack; struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; @@ -104,6 +108,7 @@ struct task_struct { 0, \ 15, \ 15, \ +/* signals */ 0,{{},},0, \ 0, \ /* ec,brk... */ 0,0,0,0,0, \ &init_task.task, 0, 0, 0,\ @@ -112,8 +117,8 @@ struct task_struct { {NULL,}, \ { \ {0, 0}, \ - {0xfff, 0xc0fa00}, \ - {0xfff, 0xc0f200}, \ + {0x9f, 0xc0fa00}, \ + {0x9f, 0xc0f200}, \ }, \ {0, PAGE_SIZE + (long)&init_task, 0x10, 0, 0, 0, 0, (long)&pg_dir, \ 0, 0, 0, 0, 0, 0, 0, 0, \ diff --git a/include/linux/sys.h b/include/linux/sys.h index 5d663422b281366919483de6b4c15c7721ea3fb3..0a65c9c26fbe31097d4b49e7c1c65c5fb673af4e 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -46,7 +46,7 @@ extern int sys_dup(); //extern int sys_brk(); //extern int sys_setgid(); //extern int sys_getgid(); -//extern int sys_signal(); +extern int sys_signal(); //extern int sys_geteuid(); //extern int sys_getegid(); //extern int sys_acct(); @@ -56,7 +56,7 @@ extern int sys_dup(); //extern int sys_fcntl(); //extern int sys_mpx(); //extern int sys_setpgid(); -//extern int sys_ulimit(); +extern int sys_ulimit(); //extern int sys_uname(); //extern int sys_umask(); //extern int sys_chroot(); @@ -135,25 +135,25 @@ fn_ptr sys_call_table[] = { sys_rmdir, sys_dup, -// sys_pipe, -// sys_times, -// sys_prof, -// sys_brk, -// sys_setgid, -// -// sys_getgid, -// sys_signal, -// sys_geteuid, -// sys_getegid, -// sys_acct, -// sys_phys, -// -// sys_lock, -// sys_ioctl, -// sys_fcntl, -// sys_mpx, -// sys_setpgid, -// sys_ulimit, + 0, // sys_pipe, + 0, // sys_times, + 0, // sys_prof, + 0, // sys_brk, + 0, // sys_setgid, + + 0, // sys_getgid, + sys_signal, + 0, // sys_geteuid, + 0, // sys_getegid, + 0, // sys_acct, + 0, // sys_phys, + + 0, // sys_lock, + 0, // sys_ioctl, + 0, // sys_fcntl, + 0, // sys_mpx, + 0, // sys_setpgid, + sys_ulimit, // // sys_uname, // sys_umask, diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 0000000000000000000000000000000000000000..a5a01f9f64517fe72fb135b8bdcd08b595e4326d --- /dev/null +++ b/include/signal.h @@ -0,0 +1,74 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include + +typedef int sig_atomic_t; +typedef unsigned int sigset_t; + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGUNUSED 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +#define SA_NOCLDSTOP 1 +#define SA_INTERRUPT 0x20000000 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 + +#define SIG_DFL ((void (*)(int))0) +#define SIG_IGN ((void (*)(int))1) +#define SIG_ERR ((void (*)(int))-1) + +#ifdef notdef +#define sigemptyset(mask) ((*(mask) = 0), 1) +#define sigfillset(mask) ((*(mask) = ~0), 1) +#endif + +struct sigaction { + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void (*sa_restorer)(void); +}; + +void (*signal(int _sig, void (*_func)(int)))(int); +int raise(int sig); +int kill(pid_t pid, int sig); +int sigaddset(sigset_t *mask, int signo); +int sigdelset(sigset_t *mask, int signo); +int sigemptyset(sigset_t *mask); +int sigfillset(sigset_t *mask); +int sigismember(sigset_t *mask, int signo); +int sigpending(sigset_t *set); +int sigprocmask(int how, sigset_t *set, sigset_t *oldset); +int sigsuspend(sigset_t *sigmask); +int sigaction(int sig, struct sigaction *act, struct sigaction *oldact); + +#endif diff --git a/include/sys/types.h b/include/sys/types.h index d5c3861a36e9d1ef3cb7222bf48a0de8bdeea8f8..c138035fc4318c837a57bff360a871167a8139f2 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -3,6 +3,7 @@ typedef long off_t; +typedef int pid_t; typedef unsigned short mode_t; typedef unsigned short ino_t; typedef unsigned short gid_t; diff --git a/kernel/Makefile b/kernel/Makefile index 157b8f3391a30ced746e0defefbe0e965b6b34b8..7c5d5c0fc9944a71dfcd570441cda6b4cd338cbe 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -3,7 +3,7 @@ CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno- LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include OBJS := head.o main.o sys_call.o asm.o sched.o printk.o vsprintf.o mktime.o \ - traps.o fork.o panic.o sys.o \ + traps.o fork.o panic.o sys.o signal.o \ chr_drv/chr_drv.a blk_drv/blk_drv.a ../mm/mm.o ../lib/lib.a ../fs/fs.o system: $(OBJS) @@ -45,6 +45,9 @@ mktime.o : mktime.c sys.o : sys.c $(GCC) $(CCFLAG) -o $@ $< +signal.o : signal.c + $(GCC) $(CCFLAG) -o $@ $< + chr_drv/chr_drv.a: chr_drv/*.c cd chr_drv; make chr_drv.a; cd .. diff --git a/kernel/exit.c b/kernel/exit.c new file mode 100644 index 0000000000000000000000000000000000000000..0bad7ef8463673b722289ee8108b12dbb75584e9 --- /dev/null +++ b/kernel/exit.c @@ -0,0 +1,49 @@ +#define DEBUG_PROC_TREE + +#include +#include +#include + +#include +#include +#include +#include + +extern int sys_pause(); +extern int sys_close(int fd); + +volatile void do_exit(long code) { + struct task_struct *p; + int i; + + free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); + free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); + + for (i=0 ; ifilp[i]) + sys_close(i); + } + + iput(current->pwd); + current->pwd = NULL; + iput(current->root); + current->root = NULL; + iput(current->executable); + current->executable = NULL; + iput(current->library); + current->library = NULL; + current->state = TASK_ZOMBIE; + current->exit_code = code; + + if ((current->p_pptr->pgrp != current->pgrp) && + (current->p_pptr->session == current->session) && + is_orphaned_pgrp(current->pgrp) && + has_stopped_jobs(current->pgrp)) { + + +} + +int sys_exit(int error_code) { + do_exit((error_code&0xff)<<8); +} + diff --git a/kernel/sched.c b/kernel/sched.c index 01a9c4718f1dd6b849a29e3a4fc376584acd64b3..a172eede6f6c1b30ffc9d68a2a44c1b3fceedb7c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4,6 +4,12 @@ #include #include #include +#include + +#include + +#define _S(nr) (1<<((nr)-1)) +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) #define COUNTER 100 @@ -39,6 +45,15 @@ void schedule() { int i,next,c; struct task_struct ** p; + for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if (!(*p)) + continue; + + if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) && + (*p)->state==TASK_INTERRUPTIBLE) + (*p)->state=TASK_RUNNING; + } + while(1) { c = -1; next = 0; diff --git a/kernel/signal.c b/kernel/signal.c new file mode 100644 index 0000000000000000000000000000000000000000..018dd04783ca54ccd34ec40ed7c0020cb96a522f --- /dev/null +++ b/kernel/signal.c @@ -0,0 +1,22 @@ +#include +#include +#include + +#include +#include + +int sys_signal(int signum, long handler, long restorer) { + struct sigaction tmp; + + if (signum<1 || signum>32 || signum==SIGKILL || signum==SIGSTOP) + return -EINVAL; + + tmp.sa_handler = (void (*)(int)) handler; + tmp.sa_mask = 0; + tmp.sa_flags = SA_ONESHOT | SA_NOMASK; + tmp.sa_restorer = (void (*)(void)) restorer; + handler = (long) current->sigaction[signum-1].sa_handler; + current->sigaction[signum-1] = tmp; + return handler; +} + diff --git a/kernel/sys.c b/kernel/sys.c index 9b2a9d121eb5886df5080935b09f22da68574473..8c8925895b9b6f4640a4f22ad6fbfe78ad80a94f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -16,6 +16,10 @@ int sys_time(long * tloc) { return i; } +int sys_ulimit() { + return -ENOSYS; +} + int in_group_p(gid_t grp) { int i; if (grp == current->egid) diff --git a/lib/wait.c b/lib/wait.c new file mode 100644 index 0000000000000000000000000000000000000000..f487d39943814c6a09fca4cbcf247ca7a7b935de --- /dev/null +++ b/lib/wait.c @@ -0,0 +1,11 @@ +#define __LIBRARY__ +#include + +#include + +_syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +pid_t wait(int * wait_stat) { + return waitpid(-1,wait_stat,0); +} + diff --git a/mm/memory.c b/mm/memory.c index 8f7eec95e7b7b6b99c6083cd44273f642d177a09..e8a6288cefd0dac120c838855608edf299357d91 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -254,7 +254,7 @@ void do_no_page(unsigned long error_code,unsigned long address) { struct m_inode * inode; if (address < TASK_SIZE) - printk("\n\rBAD!! KERNEL PAGE MISSING\n\r"); + printk("\n\rBAD!! KERNEL PAGE MISSING %x\n\r", address); if (address - current->start_code > TASK_SIZE) { printk("Bad things happen: nonexistent page error in do_no_page\n\r"); //do_exit();