diff --git a/fs/Makefile b/fs/Makefile index e2f2bcb03076f958058a21eba0840ce91938faaf..7229ab7efee63f1382048225dcc2764bd7ddd3a3 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -4,7 +4,7 @@ CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno- LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include OBJS := read_write.o buffer.o super.o open.o file_table.o inode.o namei.o fcntl.o char_dev.o \ - bitmap.o truncate.o exec.o + bitmap.o truncate.o exec.o ioctl.o fs.o : $(OBJS) $(LD) -m elf_i386 -r -o $@ $^ @@ -45,6 +45,9 @@ truncate.o : truncate.c exec.o : exec.c $(GCC) $(CCFLAG) -o $@ $< +ioctl.o : ioctl.c + $(GCC) $(CCFLAG) -o $@ $< + clean : -rm *.o diff --git a/fs/ioctl.c b/fs/ioctl.c new file mode 100644 index 0000000000000000000000000000000000000000..69ca8407baaa1b3d03a3a7118fcf69149fea6f52 --- /dev/null +++ b/fs/ioctl.c @@ -0,0 +1,10 @@ + +#include +#include +#include + +#include +int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { + return 0; +} + diff --git a/include/linux/sched.h b/include/linux/sched.h index 8c08d6f07147a776faf695e2e7a8a36faaa9ca67..dd2d223eef091ed70d3bef1fdfb688892517d4a2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #define TASK_RUNNING 0 @@ -83,11 +84,17 @@ struct task_struct { long signal; struct sigaction sigaction[32]; long blocked; - long pid; + int exit_code; unsigned long start_code,end_code,end_data,brk,start_stack; + long pid,pgrp,session,leader; + int groups[NGROUPS]; struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; unsigned short uid,euid,suid; unsigned short gid,egid,sgid; + unsigned long timeout,alarm; + long utime,stime,cutime,cstime,start_time; + + unsigned int flags; /* file info */ int tty; @@ -109,10 +116,13 @@ struct task_struct { 15, \ 15, \ /* signals */ 0,{{},},0, \ - 0, \ -/* ec,brk... */ 0,0,0,0,0, \ +/* ec,brk... */ 0, 0,0,0,0,0, \ +/* pid etc.. */ 0,0,0,0, \ +/* suppl grps*/ {NOGROUP,}, \ &init_task.task, 0, 0, 0,\ - 0,0,0,0,0,0, \ +/* uid etc */ 0,0,0,0,0,0, \ +/* timeout */ 0,0,0,0,0,0,0, \ +/* flags */ 0, \ 0,0022,NULL,NULL,NULL,NULL,0, \ {NULL,}, \ { \ diff --git a/include/linux/sys.h b/include/linux/sys.h index e2e4712a0670e0ac4aa66c440e1f78952498db16..3c7ba089825a7f8432607d84f4b03a1a2f694cc2 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -1,5 +1,5 @@ extern int sys_setup(); -//extern int sys_exit(); +extern int sys_exit(); extern int sys_fork(); extern int sys_read(); extern int sys_write(); @@ -11,28 +11,28 @@ extern int sys_close(); //extern int sys_unlink(); extern int sys_execve(); extern int sys_chdir(); -//extern int sys_time(); +extern int sys_time(); //extern int sys_mknod(); //extern int sys_chmod(); //extern int sys_chown(); //extern int sys_break(); //extern int sys_stat(); //extern int sys_lseek(); -//extern int sys_getpid(); +extern int sys_getpid(); //extern int sys_mount(); //extern int sys_umount(); //extern int sys_setuid(); -//extern int sys_getuid(); +extern int sys_getuid(); //extern int sys_stime(); //extern int sys_ptrace(); //extern int sys_alarm(); extern int sys_fstat(); -//extern int sys_pause(); +extern int sys_pause(); //extern int sys_utime(); //extern int sys_stty(); //extern int sys_gtty(); //extern int sys_access(); -//extern int sys_nice(); +extern int sys_nice(); //extern int sys_ftime(); extern int sys_sync(); //extern int sys_kill(); @@ -45,14 +45,14 @@ extern int sys_dup(); //extern int sys_prof(); extern int sys_brk(); //extern int sys_setgid(); -//extern int sys_getgid(); +extern int sys_getgid(); extern int sys_signal(); -//extern int sys_geteuid(); -//extern int sys_getegid(); +extern int sys_geteuid(); +extern int sys_getegid(); //extern int sys_acct(); //extern int sys_phys(); //extern int sys_lock(); -//extern int sys_ioctl(); +extern int sys_ioctl(); //extern int sys_fcntl(); //extern int sys_mpx(); //extern int sys_setpgid(); @@ -62,7 +62,7 @@ extern int sys_ulimit(); //extern int sys_chroot(); //extern int sys_ustat(); //extern int sys_dup2(); -//extern int sys_getppid(); +extern int sys_getppid(); //extern int sys_getpgrp(); //extern int sys_setsid(); //extern int sys_sigaction(); @@ -88,7 +88,7 @@ extern int sys_ulimit(); fn_ptr sys_call_table[] = { sys_setup, - 0, /*sys_exit*/ + sys_exit, sys_fork, sys_read, sys_write, @@ -101,7 +101,7 @@ fn_ptr sys_call_table[] = { 0, //sys_unlink, sys_execve, sys_chdir, - 0, //sys_time, + sys_time, 0, //sys_mknod, 0, //sys_chmod, @@ -109,24 +109,24 @@ fn_ptr sys_call_table[] = { 0, //sys_break, 0, //sys_stat, 0, //sys_lseek, - 0, //sys_getpid, + sys_getpid, 0, //sys_mount, 0, //sys_umount, 0, //sys_setuid, - 0, //sys_getuid, + sys_getuid, 0, //sys_stime, 0, //sys_ptrace, 0, //sys_alarm, sys_fstat, - 0, //sys_pause, + sys_pause, 0, //sys_utime, 0, //sys_stty, 0, //sys_gtty, 0, //sys_access, - 0, //sys_nice, + sys_nice, 0, //sys_ftime, sys_sync, 0, //sys_kill, @@ -141,50 +141,50 @@ fn_ptr sys_call_table[] = { sys_brk, 0, // sys_setgid, - 0, // sys_getgid, + sys_getgid, sys_signal, - 0, // sys_geteuid, - 0, // sys_getegid, + sys_geteuid, + sys_getegid, 0, // sys_acct, 0, // sys_phys, 0, // sys_lock, - 0, // sys_ioctl, + sys_ioctl, 0, // sys_fcntl, 0, // sys_mpx, 0, // sys_setpgid, sys_ulimit, -// -// sys_uname, -// sys_umask, -// sys_chroot, -// sys_ustat, -// sys_dup2, -// sys_getppid, -// -// sys_getpgrp, -// sys_setsid, -// sys_sigaction, -// sys_sgetmask, -// sys_ssetmask, -// -// sys_setreuid, -// sys_setregid, -// sys_sigsuspend, -// sys_sigpending, -// sys_sethostname, -// sys_setrlimit, -// sys_getrlimit, -// sys_getrusage, -// sys_gettimeofday, -// sys_settimeofday, -// sys_getgroups, -// sys_setgroups, -// sys_select, -// sys_symlink, -// sys_lstat, -// sys_readlink, -// sys_uselib + + 0, // sys_uname, + 0, // sys_umask, + 0, // sys_chroot, + 0, // sys_ustat, + 0, // sys_dup2, + sys_getppid, + 0, // + 0, // sys_getpgrp, + 0, // sys_setsid, + 0, // sys_sigaction, + 0, // sys_sgetmask, + 0, // sys_ssetmask, + 0, // + 0, // sys_setreuid, + 0, // sys_setregid, + 0, // sys_sigsuspend, + 0, // sys_sigpending, + 0, // sys_sethostname, + 0, // sys_setrlimit, + 0, // sys_getrlimit, + 0, // sys_getrusage, + 0, // sys_gettimeofday, + 0, // sys_settimeofday, + 0, // sys_getgroups, + 0, // sys_setgroups, + 0, // sys_select, + 0, // sys_symlink, + 0, // sys_lstat, + 0, // sys_readlink, + 0, // sys_uselib }; int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); diff --git a/include/linux/tty.h b/include/linux/tty.h index fec7ad9f435f9b157aa33f1eb2b3b68ca0c93fe5..23a76b13dfc4368eaf1dd4970d49cabc3e916ab1 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -34,6 +34,7 @@ struct tty_queue { struct tty_struct { struct termios termios; int pgrp; + int session; int stopped; void (*write)(struct tty_struct * tty); struct tty_queue read_q; @@ -41,6 +42,12 @@ struct tty_struct { struct tty_queue secondary; }; +extern struct tty_struct tty_table[]; +extern int fg_console; + +#define TTY_TABLE(nr) \ +(tty_table + ((nr) ? (((nr) < 64)? (nr)-1:(nr)) : fg_console)) + #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" void con_init(); diff --git a/include/sys/param.h b/include/sys/param.h index 3963ebbca56e9c3fc064985f11b9950d3436e404..2f233772b77633c071de8ce0293db8be28d7255f 100644 --- a/include/sys/param.h +++ b/include/sys/param.h @@ -2,5 +2,6 @@ #define _PARAM_H #define NGROUPS 32 +#define NOGROUP -1 #endif diff --git a/include/sys/wait.h b/include/sys/wait.h new file mode 100644 index 0000000000000000000000000000000000000000..e34e0950c198f0f9497ee463f8d3e5a5b2bfb182 --- /dev/null +++ b/include/sys/wait.h @@ -0,0 +1,6 @@ +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H + + + +#endif diff --git a/kernel/Makefile b/kernel/Makefile index 7c5d5c0fc9944a71dfcd570441cda6b4cd338cbe..2d048e04685e0357c5eb4f66e96012c1318bba4f 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 signal.o \ + traps.o fork.o panic.o sys.o signal.o exit.o \ chr_drv/chr_drv.a blk_drv/blk_drv.a ../mm/mm.o ../lib/lib.a ../fs/fs.o system: $(OBJS) @@ -48,6 +48,9 @@ sys.o : sys.c signal.o : signal.c $(GCC) $(CCFLAG) -o $@ $< +exit.o : exit.c + $(GCC) $(CCFLAG) -o $@ $< + chr_drv/chr_drv.a: chr_drv/*.c cd chr_drv; make chr_drv.a; cd .. diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c index 9e559e540e4e646ff1b2b92071a55e2ac64def19..acd73b05e47d64b6d24060693f4b4d412d83a575 100644 --- a/kernel/blk_drv/floppy.c +++ b/kernel/blk_drv/floppy.c @@ -167,7 +167,7 @@ void rw_interrupt() { } void setup_rw_floppy() { - printk("setup_rw_floppy\n"); + //printk("setup_rw_floppy\n"); setup_DMA(); do_floppy = rw_interrupt; output_byte(command); diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c index bcabc6b82ad211b78eaab5f9fa49055834e3f33e..80e704a03840ef9cbf95ec6841207a175ac49feb 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -34,6 +34,7 @@ struct tty_struct tty_table[] = { }, 0, 0, + 0, con_write, {0, 0, 0, 0, ""}, {0, 0, 0, 0, ""}, diff --git a/kernel/exit.c b/kernel/exit.c index 0bad7ef8463673b722289ee8108b12dbb75584e9..03641090302ff4bbf46465ed61cd6a8c34261dcd 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -12,7 +12,76 @@ extern int sys_pause(); extern int sys_close(int fd); -volatile void do_exit(long code) { +static inline int send_sig(long sig,struct task_struct * p,int priv) { + if (!p) + return -EINVAL; + if (!priv && (current->euid!=p->euid) && !suser()) + return -EPERM; + if ((sig == SIGKILL) || (sig == SIGCONT)) { + if (p->state == TASK_STOPPED) + p->state = TASK_RUNNING; + p->exit_code = 0; + p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) | + (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1))); + } + if ((int) p->sigaction[sig-1].sa_handler == 1) + return 0; + if ((sig >= SIGSTOP) && (sig <= SIGTTOU)) + p->signal &= ~(1<<(SIGCONT-1)); + p->signal |= (1<<(sig-1)); + return 0; +} + +int kill_pg(int pgrp, int sig, int priv) { + struct task_struct **p; + int err,retval = -ESRCH; + int found = 0; + + if (sig<1 || sig>32 || pgrp<=0) + return -EINVAL; + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if ((*p)->pgrp == pgrp) { + if (sig && (err = send_sig(sig,*p,priv))) + retval = err; + else + found++; + } + } + + return(found ? 0 : retval); +} + +int is_orphaned_pgrp(int pgrp) { + struct task_struct **p; + + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if (!(*p) || + ((*p)->pgrp != pgrp) || + ((*p)->state == TASK_ZOMBIE) || + ((*p)->p_pptr->pid == 1)) + continue; + if (((*p)->p_pptr->pgrp != pgrp) && + ((*p)->p_pptr->session == (*p)->session)) + return 0; + } + + return 1; +} + +static int has_stopped_jobs(int pgrp) { + struct task_struct ** p; + + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { + if ((*p)->pgrp != pgrp) + continue; + if ((*p)->state == TASK_STOPPED) + return(1); + } + + return 0; +} + +void do_exit(long code) { struct task_struct *p; int i; @@ -39,11 +108,60 @@ volatile void do_exit(long code) { (current->p_pptr->session == current->session) && is_orphaned_pgrp(current->pgrp) && has_stopped_jobs(current->pgrp)) { + kill_pg(current->pgrp,SIGHUP,1); + kill_pg(current->pgrp,SIGCONT,1); + } + + current->p_pptr->signal |= (1<<(SIGCHLD-1)); + + if (p = current->p_cptr) { + while (1) { + p->p_pptr = task[1]; + if (p->state == TASK_ZOMBIE) + task[1]->signal |= (1<<(SIGCHLD-1)); + if ((p->pgrp != current->pgrp) && + (p->session == current->session) && + is_orphaned_pgrp(p->pgrp) && + has_stopped_jobs(p->pgrp)) { + kill_pg(p->pgrp,SIGHUP,1); + kill_pg(p->pgrp,SIGCONT,1); + } + + if (p->p_osptr) { + p = p->p_osptr; + continue; + } + + p->p_osptr = task[1]->p_cptr; + task[1]->p_cptr->p_ysptr = p; + task[1]->p_cptr = current->p_cptr; + current->p_cptr = 0; + break; + } + } + + if (current->leader) { + struct task_struct **p; + struct tty_struct *tty; + + if (current->tty >= 0) { + tty = tty_table + current->tty; + if (tty->pgrp>0) + kill_pg(tty->pgrp, SIGHUP, 1); + tty->pgrp = 0; + tty->session = 0; + } + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) + if ((*p)->session == current->session) + (*p)->tty = -1; + } + schedule(); } int sys_exit(int error_code) { do_exit((error_code&0xff)<<8); + return 0; } diff --git a/kernel/main.c b/kernel/main.c index 2bfc4614f9ce00e6825f3f54ecd9f9d2d5ef643e..2bd10c441e3d06892fb861a42942517aeb3ddc8c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -4,6 +4,7 @@ #include inline _syscall0(int, fork); +inline _syscall0(int, pause) inline _syscall1(int, setup, void *, BIOS) inline _syscall0(int, sync) @@ -125,6 +126,7 @@ void main() { "movw %ax, %gs:(%edi)\n\r"); for(;;); + //pause(); } int printf(const char* fmt, ...) { @@ -138,20 +140,9 @@ int printf(const char* fmt, ...) { return i; } -void init() { - int pid, i; +static void easy_shell() { + int i; char a[10]; - setup((void *) &drive_info); - (void)open("/dev/tty0", O_RDWR, 0); - (void) dup(0); - (void) dup(0); - - /* - if (!(pid=fork())) { - printf("read to start shell\n"); - execve("/bin/sh",argv,envp); - }*/ - while (1) { i = read(0, a, 9); a[i - 1] = 0; @@ -175,6 +166,24 @@ void init() { sync(); } } +} + +static void run_sh() { + int pid; + if (!(pid=fork())) { + printf("read to start shell\n"); + execve("/bin/sh",argv,envp); + } +} + +void init() { + setup((void *) &drive_info); + (void)open("/dev/tty0", O_RDWR, 0); + (void) dup(0); + (void) dup(0); + + //run_sh(); + easy_shell(); printf("Free mem: %d bytes\n\r",memory_end-main_memory_start); } diff --git a/kernel/sched.c b/kernel/sched.c index a172eede6f6c1b30ffc9d68a2a44c1b3fceedb7c..c721efd2df6afa3f3f28302ce51de89f045b2bf8 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -79,6 +79,12 @@ void schedule() { switch_to(next); } +int sys_pause() { + current->state = TASK_INTERRUPTIBLE; + schedule(); + return 0; +} + static inline void __sleep_on(struct task_struct** p, int state) { struct task_struct* tmp; @@ -249,6 +255,36 @@ void do_timer(long cpl) { schedule(); } +int sys_getpid() { + return current->pid; +} + +int sys_getppid() { + return current->p_pptr->pid; +} + +int sys_getuid() { + return current->uid; +} + +int sys_geteuid() { + return current->euid; +} + +int sys_getgid() { + return current->gid; +} + +int sys_getegid() { + return current->egid; +} + +int sys_nice(long increment) { + if (current->priority-increment>0) + current->priority -= increment; + return 0; +} + void sched_init() { int i; struct desc_struct * p; diff --git a/mm/memory.c b/mm/memory.c index e8a6288cefd0dac120c838855608edf299357d91..9b6fa72895264d3175276afdb2046441a92fa9d8 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -260,6 +260,7 @@ void do_no_page(unsigned long error_code,unsigned long address) { //do_exit(); } + printk("do_no_page, address is 0x%x\n", address); address &= 0xfffff000; tmp = address - current->start_code; @@ -275,7 +276,6 @@ void do_no_page(unsigned long error_code,unsigned long address) { oom(); block = 1 + tmp / BLOCK_SIZE; - printk("do_no_page, tmp, block is %d, %d\n", tmp, block); for (i = 0; i < 4; block++, i++) {