diff options
| author | Miguel <m.i@gmx.at> | 2018-09-18 03:03:28 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-18 03:03:28 +0200 |
| commit | 2d91384197847a7e8fe2c3f548918a8277d3086d (patch) | |
| tree | 7c93404e290a0ffbdaf9a8a94766d7bd0fd6e4f2 | |
| parent | 06e6e427c76bdb88a7f72dd04411d95a4bda3270 (diff) | |
sysfs, errno, improve foolshell, etc
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | driver/keyboard.c | 24 | ||||
| -rw-r--r-- | fs/fd.c | 101 | ||||
| -rw-r--r-- | fs/fd.h | 8 | ||||
| -rw-r--r-- | fs/mount.c | 13 | ||||
| -rw-r--r-- | fs/mount.h | 3 | ||||
| -rw-r--r-- | fs/sysfs.c | 46 | ||||
| -rw-r--r-- | fs/sysfs.h | 1 | ||||
| -rw-r--r-- | kernel/fifo.c | 1 | ||||
| -rw-r--r-- | kernel/kernel.c | 4 | ||||
| -rw-r--r-- | kernel/kmalloc.c | 10 | ||||
| -rw-r--r-- | kernel/kmalloc.h | 4 | ||||
| -rw-r--r-- | kernel/mem.c | 8 | ||||
| -rw-r--r-- | kernel/mem.h | 3 | ||||
| -rw-r--r-- | kernel/scheduler.c | 2 | ||||
| -rw-r--r-- | kernel/syscalls.c | 60 | ||||
| -rw-r--r-- | userspace/Makefile | 7 | ||||
| -rw-r--r-- | userspace/foolshell.c | 279 | ||||
| -rw-r--r-- | userspace/init.c | 2 |
19 files changed, 358 insertions, 225 deletions
@@ -86,10 +86,11 @@ FoolOS is tested/developed on the following emulators/machines Todos ----- + * Newlib errno / return value / argv / env -* pipe\_syscall +* pipe\_syscall / execve: support hashbangs * DMA where possible! -* Mouse & KB processing in seperate task. +* optimized Mouse & KB processing in seperate task. (Kb all chars and different layouts) * Kernel Stuff Reentrancy? * Cleanup syscalls * Writing to ext2 RAM-image @@ -105,6 +106,8 @@ Todos * GUI / Window Manager (update\_rect, etc..) * Porting (ncurses, gcc, binutils, vim, apache...) +* Crazy & Funny terminal effects while typing (idea) + Disclaimer ---------- diff --git a/driver/keyboard.c b/driver/keyboard.c index d276f51..61b8e5f 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -11,10 +11,10 @@ static bool shift_r=false; static bool capslock=false; static uint32_t kb_stream; +static char num_syms[]={')','!','@','#','$','%','^','&','*','('}; static void put(uint8_t c) { - klog("%c",c); syscall_write(kb_stream,(char *)&c,1); } @@ -25,6 +25,7 @@ void keyboard_init(uint32_t s) void keyboard_handle(uint8_t in) { + // klog("kb_in 0x%x",in); uint8_t make_alpha[]={ 0x1e, // A 0x30, // B @@ -143,6 +144,7 @@ void keyboard_handle(uint8_t in) if(break_slash==in) { ascii='/'; + if(shift_l||shift_r||capslock) ascii='?'; match=true; } else if(break_key_space==in) @@ -153,31 +155,43 @@ void keyboard_handle(uint8_t in) else if(in==0xB4) { ascii='.'; + if(shift_l||shift_r||capslock) ascii='<'; match=true; } else if(in==0xB3) { ascii=','; + if(shift_l||shift_r||capslock) ascii='>'; match=true; } else if(in==0x8D) { - ascii='+'; + ascii='='; + if(shift_l||shift_r||capslock) ascii='+'; match=true; } else if(in==0x8C) { ascii='-'; + if(shift_l||shift_r||capslock) ascii='_'; match=true; } else if(in==0x9A) { ascii='['; + if(shift_l||shift_r||capslock) ascii='{'; match=true; } else if(in==0x9B) { ascii=']'; + if(shift_l||shift_r||capslock) ascii='}'; + match=true; + } + else if(in==0xab) + { + ascii='\\'; + if(shift_l||shift_r||capslock) ascii='|'; match=true; } else if(break_key_backspace==in) @@ -198,7 +212,7 @@ void keyboard_handle(uint8_t in) } else if(break_key_tab==in) { - ascii=0x09; + ascii='\t'; match=true; } @@ -223,6 +237,10 @@ void keyboard_handle(uint8_t in) if(break_num[i]==in) { ascii=('0'+i); + if(shift_l||shift_r||capslock) // capslock makes trouble :( + { + ascii=num_syms[i]; + } match=true; break; } @@ -4,6 +4,9 @@ #include "kmalloc.h" #include "ext2.h" #include "log.h" +#include "lib/string/string.h" +#include "lib/printf/printf.h" +#include "ringbuffer.h" bool fd_write(fd* f,uint8_t c) { @@ -20,21 +23,14 @@ bool fd_has(fd* f) return f->has(f->data); } -bool fd_close(fd* f) +bool fd_eof(fd* f) { - return f->close(f->data); + return f->eof(f->data); } -fd fd_from_fifo(fifo* fif) +bool fd_close(fd* f) { - fd f; - f.type=FD_TYPE_FIFO_BUFFERED; - f.data=fif; - f.read=fifo_get; - f.write=fifo_put; -// f.close=fd_close; - f.has=fifo_has; - return f; + return f->close(f->data); } //---- @@ -62,17 +58,75 @@ uint8_t ext2_read(uint32_t* data) bool ext2_has(uint32_t* data) { + return 1; +} + +bool ext2_eof(uint32_t* data) +{ uint32_t save=data[1]; uint32_t c=ext2_read_inode(VMEM_EXT2_RAMIMAGE,data[0],&c,&data[1],1); data[1]=save; - return (c>0); - + return (c==0); } + void ext2_close(void* x) { kbfree(x); } +uint8_t sysfs_get(uint32_t *data) +{ + return ringbuffer_get(data); +} + +bool sysfs_has(uint32_t *data) +{ + return true; +} + +bool sysfs_eof(uint32_t *data) +{ + return !ringbuffer_has(data); +} + +void sysfs_close(uint32_t *data) +{ + ringbuffer *r=data; + ringbuffer_free(data); // free ringbuffer buffer + kbfree(data); // free memory holding ringbuffer information +} + +void get_sysfs_data(ringbuffer *r,char *format_string, ...) +{ + char buf[256]; + va_list va; + va_start(va,format_string); + tfp_vsprintf(buf,format_string,va); + va_end(va); + + for(int i=0;i<strlen(buf);i++) + ringbuffer_put(r,buf[i]); + + ringbuffer_put(r,'\n'); +} + +bool fifo_eof(uint32_t* data) +{ + return false; +} +fd fd_from_fifo(fifo* fif) +{ + fd f; + f.type=FD_TYPE_FIFO_BUFFERED; + f.data=fif; + f.read=fifo_get; + f.write=fifo_put; + f.eof=fifo_eof; +// f.close=fd_close; //TODO.. etc also otehr and cleanups + f.has=fifo_has; + return f; +} + fd fd_from_path(char* path) { fd f; @@ -81,6 +135,27 @@ fd fd_from_path(char* path) f.read=ext2_read; f.write=ext2_write; f.close=ext2_close; + f.eof=ext2_eof; f.has=ext2_has; return f; } + +fd fd_from_sysfs(void(*g)(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...))) +{ + fd f; + f.type=FD_TYPE_SYSFS; + f.data=kballoc(1); + ringbuffer r=ringbuffer_init(1); + + g(&r,get_sysfs_data); + memcpy(f.data,&r,sizeof(ringbuffer)); + + f.read=sysfs_get; + f.write=0; + f.close=sysfs_close; + f.has=sysfs_has; + f.eof=sysfs_eof; + + return f; +} + @@ -7,6 +7,7 @@ #include <stdbool.h> #include "fifo.h" +#include "ringbuffer.h" /* typedef struct @@ -27,7 +28,8 @@ typedef struct enum FD_TYPE{ FD_TYPE_FIFO_BUFFERED=1, FD_TYPE_EXT2_FILE=2, - FD_TYPE_EXT2_DIR=3 + FD_TYPE_EXT2_DIR=3, + FD_TYPE_SYSFS=4 }; typedef struct fd_struct @@ -35,6 +37,7 @@ typedef struct fd_struct bool (*write)(struct fd_struct*,uint8_t); uint8_t (*read)(struct fd_struct*); bool (*has)(struct fd_struct*); + bool (*eof)(struct fd_struct*); bool (*close)(struct fd_struct*); uint8_t type; @@ -43,10 +46,11 @@ typedef struct fd_struct uint8_t fd_read(fd*); bool fd_has(fd*); +bool fd_eof(fd*); bool fd_write(fd*,uint8_t); bool fd_close(fd*); fd fd_from_fifo(fifo* f); fd fd_from_path(char *path); -//fd fd_from_sysfs(void(*g)(void (*f)(char *fmt, ...))); +fd fd_from_sysfs(void(*g)(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...))); #endif @@ -18,7 +18,7 @@ char *mount_type_to_str(uint32_t t) { case MOUNT_TYPE_EXT2: return "EXT2"; case MOUNT_TYPE_PIPES: return "PIPES"; - case MOUNT_TYPE_SYS: return "SYS"; + case MOUNT_TYPE_SYS: return "SYSFS"; } return "UNKNOWN"; } @@ -39,6 +39,16 @@ void mount_dump() } } +void mount_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...)) +{ + f(r,"mounts:"); + for(int i=0;i<mounts_count;i++) + { + mount *m=&mounts[i]; + f(r,"%s mounted at: %s ",mount_type_to_str(m->type),m->path); + } +} + static uint32_t check_match(char *p1, char *p2) { uint32_t c=0; @@ -84,7 +94,6 @@ fd mount_file_open(char *path) { mount m; char *p=get_mount_for_path(path,&m); - klog("%s in %s",p,m.path); return m.mount_file_open(&m,p); } @@ -50,4 +50,7 @@ fd mount_file_open(char *path); /** TODO: should use fd number instead of PATH on each call*/ int mount_read_dir (char *path, fs_dirent *dirs, uint32_t *pos); +/** sysfs interface */ +void mount_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...)); + #endif diff --git a/fs/sysfs.c b/fs/sysfs.c new file mode 100644 index 0000000..57a56c8 --- /dev/null +++ b/fs/sysfs.c @@ -0,0 +1,46 @@ +#include "mount.h" +#include "sysfs.h" + +#include "mem.h" +#include "kmalloc.h" +#include "mount.h" + +#include "log.h" + +#include "lib/string/string.h" + +static const char* names[] = {"/mem","/kmalloc","/mount"}; +static uint32_t map[]={mem_sysfs,kmalloc_sysfs,mount_sysfs}; +static uint32_t count=3; + + +/* mount interface */ + +fd sysfs_file_open(mount *m,char *path) +{ + klog("sysfs file open: %s",path); + for (int i=0;i<count;i++) + { + if(!strcmp(path,names[i])) + return fd_from_sysfs(map[i]); + } + return fd_from_sysfs(map[0]); +} + +int sysfs_read_dir(mount *m,char *path, fs_dirent *dirs, uint32_t *pos) +{ + if(*pos>=count)return 0; + memcpy(dirs->name,names[*pos],strlen(names[*pos])+1); + *pos+=1; + return 1; +} + +void sysfs_mount(char* path) +{ + mount m; + m.type=MOUNT_TYPE_SYS; + memcpy(m.path,path,strlen(path)+1); + m.mount_file_open=sysfs_file_open; + m.mount_read_dir=sysfs_read_dir; + mount_add(m); +} diff --git a/fs/sysfs.h b/fs/sysfs.h new file mode 100644 index 0000000..7d09395 --- /dev/null +++ b/fs/sysfs.h @@ -0,0 +1 @@ +void sysfs_mount(char* path); diff --git a/kernel/fifo.c b/kernel/fifo.c index fadd248..10bc8ff 100644 --- a/kernel/fifo.c +++ b/kernel/fifo.c @@ -27,7 +27,6 @@ bool fifo_has(fifo* f) fifo fifo_create_buffered(uint8_t size) { if (ringbuffer_c>=FIFO_MAX_RINGBUFFERS) kpanic("ran out of ringbuffers for fifos"); - fifo f; fifo_ringbuffers[ringbuffer_c]=ringbuffer_init(size); f.data=&fifo_ringbuffers[ringbuffer_c]; diff --git a/kernel/kernel.c b/kernel/kernel.c index 0239489..072cebb 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -12,6 +12,7 @@ #include "vmem.h" //-- clean below headers --// +#include "sysfs.h" #include "testing/testing.h" #include "ext2.h" #include "apic.h" @@ -100,6 +101,9 @@ void kernel_main(uint32_t eax,uint32_t ebx) ext2_dump_info(VMEM_EXT2_RAMIMAGE); ext2_mount("/"); + // -- MOUNT SYSFS --// + sysfs_mount("/sys/"); + // -- APIC -- // klog("Advanced Programmable Interrupt Controller (APIC) config ..."); apic_init(&cfg_acpi); diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c index 6a7520a..061d68e 100644 --- a/kernel/kmalloc.c +++ b/kernel/kmalloc.c @@ -117,7 +117,7 @@ void kbfree(uint32_t pos) spinlock_release(SPINLOCK_ALLOC); } -void kmalloc_sysfs(void (*f)(char *fmt, ...)) +void kmalloc_sysfs(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...)) { uint32_t free=0; uint32_t used=0; @@ -127,8 +127,8 @@ void kmalloc_sysfs(void (*f)(char *fmt, ...)) else free++; } - f("kernel blocks allocation/deallocation"); - f("total 4096kb blocks: %d (%d bytes)",BLOCKS,BLOCKS*4096); - f("used 4096kb blocks: %d (%d bytes)",used,used*4096); - f("free 4096kb blocks: %d (%d bytes)",free,free*4096); + f(r,"kernel blocks allocation/deallocation"); + f(r,"total 4096kb blocks: %d (%d bytes)",BLOCKS,BLOCKS*4096); + f(r,"used 4096kb blocks: %d (%d bytes)",used,used*4096); + f(r,"free 4096kb blocks: %d (%d bytes)",free,free*4096); } diff --git a/kernel/kmalloc.h b/kernel/kmalloc.h index 5ca4c8c..617872b 100644 --- a/kernel/kmalloc.h +++ b/kernel/kmalloc.h @@ -20,6 +20,8 @@ #include <stdint.h> +#include "ringbuffer.h" + /** Allocate size*4096 bytes and returns a 32-bit address * and 0 if fails. * */ @@ -29,4 +31,4 @@ uint32_t kballoc (uint32_t size); void kbfree (uint32_t addr); /** Get current status for sysfs */ -void kmalloc_sysfs(void (*f)(char *fmt, ...)); +void kmalloc_sysfs(ringbuffer *r, void (*f)(ringbuffer *r, char *fmt, ...)); diff --git a/kernel/mem.c b/kernel/mem.c index 52e08b6..97450d4 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -228,9 +228,9 @@ uint32_t mem_init(multiboot_information *info) return 0; } -void mem_sysfs(void (*f)(char *fmt, ...)) +void mem_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...)) { - f("physical memory manager"); - f("free 4096kb blocks : %d",mem_free_blocks); - f("free bytes : %d",mem_free_blocks*4096); + f(r,"physical memory manager"); + f(r,"free 4096kb blocks : %d",mem_free_blocks); + f(r,"free bytes : %d",mem_free_blocks*4096); } diff --git a/kernel/mem.h b/kernel/mem.h index 85fc688..5de95a9 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -19,6 +19,7 @@ */ #include "multiboot.h" +#include "ringbuffer.h" /** * Init the physical memory manager. Please provide the multiboot_information @@ -29,4 +30,4 @@ uint32_t mem_init(multiboot_information *info); void* mem_alloc_block (); void mem_free_block(void* p); uint32_t mem_get_free_blocks_count(); -void mem_sysfs(void (*f)(char *fmt, ...)); +void mem_sysfs(ringbuffer *r, void (*f)(ringbuffer *r, char *fmt, ...)); diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 798d119..8f7f6d6 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -291,7 +291,7 @@ void task_syscall_worker() { uint32_t syscall=task_list[cpu][i].eax; - klog("task pid=%d waiting on syscall %d/%s on cpu %d slot %d.",task_list[cpu][i].pid,syscall,syscall_get_name(syscall),cpu,i); +// klog("task pid=%d waiting on syscall %d/%s on cpu %d slot %d.",task_list[cpu][i].pid,syscall,syscall_get_name(syscall),cpu,i); task_list[cpu][0].vmem=task_list[cpu][i].vmem; // switch syscall worker to pagedir of calling userprog x86_set_page_directory(task_list[cpu][0].vmem); diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 8b5040a..aa20616 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -17,6 +17,15 @@ #include "log.h" #include "timer.h" #include "mount.h" +#include "mem.h" +#include "reent.h" +#include "errno.h" + +void set_errno(int no) +{ + struct _reent *impure_ptr=VMEM_USER_NEWLIB; + impure_ptr->_errno=no; +} static fd fds[MAX_FD]; static uint32_t next_fd=0; @@ -148,7 +157,7 @@ int syscall_write(int file, char *buf, int len) */ int syscall_read(int file, char *buf, int len) { - if(fds[file].type==FD_TYPE_EXT2_FILE && !fd_has(&fds[file]))return 0; + if(fd_eof(&fds[file]))return 0; *buf=fd_read(&fds[file]); return 1; } @@ -217,36 +226,28 @@ int copy_args(char **in, char **out) return count; } -int syscall_execve(char *name, char **argv, char **env,int pid) +/** does not return on success otherwise -1 and errrno set */ +int syscall_execve(const char *name, char *const argv[], char *const env[], int pid) { + fixme("not overwrite yourself?"); int arg_count=0; while(argv[arg_count]!=NULL)arg_count++; char **argv1=VMEM_USER_ENV; - if(argv!=NULL) - { - copy_args(argv,argv1); - } - else{ - argv1=NULL; - } + if(argv!=NULL)copy_args(argv,argv1); + else argv1=NULL; char **env1=VMEM_USER_ENV+1024*2; - if(env!=NULL) - { - copy_args(env,env1); - } - else{ - env1=NULL; - } + if(env!=NULL)copy_args(env,env1); + else env1=NULL; uint32_t alloc; uint32_t entry_global=load_elf(name,&alloc); - if(!entry_global) - { - return -1; // errror loading + if(!entry_global){ + set_errno(ENOENT); + return -1; } uint32_t *stack=VMEM_USER_STACK_TOP-4*32; @@ -255,26 +256,6 @@ int syscall_execve(char *name, char **argv, char **env,int pid) *--stack=env1; task_reset(pid,entry_global,stack,alloc); return 0; - - /* try to move this to asm */ - // asm volatile("jmp ."); // loop forever - //klog("returning to jump addy (0x%08X)", entry_global); - /* - asm volatile("mov $0x08fff000,%esp"); // set stack at high end of process image - - asm volatile ("push %0" :: "r" (argv1)); - asm volatile ("push %0" :: "r" (arg_count)); - //asm volatile ("push %0" :: "r" (kballoc(1))); - asm volatile ("push %0" :: "r" (env1)); - - // push addr and return to it - asm volatile ("pushl %0"::"r"(entry_global)); - - asm volatile ("sti"); - asm volatile ("ret"); - */ - - // this is never reached! } // minihack @@ -402,7 +383,6 @@ uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, case SYSCALL_WAIT : return !task_runs(p1); case SYSCALL_READ : - if(fds[p1].type==FD_TYPE_EXT2_FILE)return 1; return fd_has(&fds[p1]); case SYSCALL_EXIT : return 1; diff --git a/userspace/Makefile b/userspace/Makefile index dbc2d0f..d39f15f 100644 --- a/userspace/Makefile +++ b/userspace/Makefile @@ -2,6 +2,8 @@ IMAGESIZE=10000 #ext2.img size in Kb ####################### +GIT_REVISION=$(shell git rev-parse HEAD) + CC=i686-foolos-gcc CC=i686-elf-gcc AS=i686-elf-as @@ -9,11 +11,13 @@ CC = @echo "Compiling (i686-elf-gcc) $<..."; i686-elf-gcc AS = @echo "Assembling (i686-elf-as) $<..."; i686-elf-as CFLAGS= -CFLAGS=-w +CFLAGS+=-DGIT_REVISION=\"$(GIT_REVISION)\" +CFLAGS+=-w CFLAGS+=-I.. CFLAGS+=-I/home/miguel/temp/foolos/usr/i686-foolos/include CFLAGS+=-O0 CFLAGS+=-g +CFLAGS+= -Werror=implicit-function-declaration LDFLAGS=-L/home/miguel/temp/foolos/usr/i686-foolos/lib/ LDLIBS=-lc -lm -lg -lnosys @@ -40,6 +44,7 @@ ext2.img: $(PROGS) @echo "Welcome to FoolOs\nWe hope you will enjoy your stay." > mnt/home/miguel/hello.txt @mkdir -p mnt/bin @mkdir -p mnt/doc/test + @mkdir -p mnt/sys # mountpoint for sysfs @cp test.txt mnt/doc/test/ @cp $(PROGS) mnt/bin @cp fonts/binfont.bin mnt/ diff --git a/userspace/foolshell.c b/userspace/foolshell.c index 0012592..e8b384e 100644 --- a/userspace/foolshell.c +++ b/userspace/foolshell.c @@ -1,47 +1,45 @@ +/** + * @file + * + * Fool's Shell + * ========= + * + * A minimalsitic and naive shell developed along the Fool OS kernel. + * TODO: Free tokenizer / dynamic size! + */ + #include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <string.h> - -#include <reent.h> +#include <errno.h> +#include <string.h> extern char **environ; -extern struct _reent *_impure_ptr; -uint8_t buf_test[1024*300]; +bool process(char *buf); +bool cd(char *path); -// -void hello() +void version() +{ + puts("Fool's Shell version git-commit:" GIT_REVISION "\ncompiled on " __DATE__ " at " __TIME__); +} +void help() { - // ascci art: http://patorjk.com/software/taag/#p=testall&f=Cards&t=Fool%20OS - puts( - - "\033c" -// "\033[36m" - -// " ______ __ ____ _____ \n" -// " / ____/___ ____ / / / __ \\/ ___/ \n" -// " / /_ / __ \\/ __ \\/ / / / / /\\__ \\ \n" -// " / __/ / /_/ / /_/ / / / /_/ /___/ / \n" -// " /_/ \\____/\\____/_/ \\____//____/ \n" -// " \n" - -// "\033[37;44m" -// " \n" - - " Welcome to FoolShell v0.12 (Compiled on " __DATE__ " at " __TIME__")\n" - " ------------------------------------------------------------------\n\n" - " Please type 'help' anytime, to show shell \"built-ins\". You can execute \n" - " user programms that are in your $PATH directory by simply typing \n" - " their filenames. Get additional information for many, of the available\n" - " commands by invoking them with --help or -h. (e.g. ls --help) \n" - " \n" - - "\033[37;40m" - ); - - printf(" Your $PATH is currently set to: %s\n",getenv("PATH")); - printf(" Type 'ls %s' to list programms on your $PATH.\n\n",getenv("PATH")); + puts( "\nfoolshell: supported built-in commands/functions:\n\n" + + "'env' - show all environment variables\n" + "'getenv [var]' - show environment variable\n" + "'setenv [var] [val]' - set environemnet variable\n" + + "'cd [dir]' - change directory (set $PWD)\n" + "'[binary] [params...]' - run a binary\n" + "'[binary] [params...] &' - run a binary in background\n" + " TODO - pipes\n" + + "'help' - show this message\n" + "'exit' - exit running foolshell\n\n"); + } void prompt() @@ -49,23 +47,32 @@ void prompt() printf("\033[36mfool\033[37m@\033[32mhill\033[33m:%s%s\033[37m",getenv("PWD"),getenv("PS1")); } - int main(int argc, char **argv) { - bool silent=false; for(int i=0;i<argc;i++) { - if(!strcmp(argv[i],"--silent"))silent=true; + if(!strcmp(argv[i],"--version")) + { + version(); + return 0; + } + + if(!strcmp(argv[i],"--help")) + { + help(); + return 0; + } } - - if(!silent)hello(); char *buf=calloc(sizeof(char),256); + // input and output without buffering setvbuf(stdin,NULL,_IONBF,0); setvbuf(stdout,NULL,_IONBF,0); - while(1) + printf("\033c"); // clear screen + + while(1) // process commands until exit { prompt(); int bl=0; @@ -89,19 +96,18 @@ int main(int argc, char **argv) } } - //fgets(buf,255,stdin); - //buf[strlen(buf)-1]=0; // remove \n - //printf("[%s]",buf); - process(buf); + if(!process(buf))break; // process input and return if exit } return 0; } -char **tokenize(char *buf) +// break the input in tokens on spaces +char **tokenize(char *buf,char chr) { char **token; token=malloc(10*sizeof(char*)); + token=realloc(token,20*sizeof(char*)); int l=strlen(buf); @@ -114,13 +120,13 @@ char **tokenize(char *buf) token[c]=malloc(256); //skip all the whitespace - while(buf[i]==' '&&i<l)i++; + while(buf[i]==chr&&i<l)i++; if(i==l)break; //get token int t=0; - while(buf[i]!=' '&&i<l) + while(buf[i]!=chr&&i<l) { token[c][t]=buf[i]; t++; @@ -136,129 +142,106 @@ char **tokenize(char *buf) return token; } -int process(char *buf) +bool process(char *buf) { - char **token=tokenize(buf); + char **token=tokenize(buf,' '); char *command=token[0]; - // puts(command); - // copied from trottelshell - - if(!strcmp(command,"help")) - { - puts( "\nfoolshell: supported built-in commands:\n\n" - "'help' - show this message\n" - "'echo [string]' - print given string to stdout\n" - "'getenv [var]' - show environment variable\n" - "'putenv/setenv [var] [val]' - set environemnet variable\n" - "'env' - show all environment variables\n" - "'cd [dir]' - change directory (set $PWD)\n" - "'exit' - exit running foolshell\n\n"); - } - else if(!strcmp(command,"cd")) + if(!strcmp(command,"help"))help(); + else if(!strcmp(command,"cd"))cd(token[1]); + else if(!strcmp(command,"exit")) return false; + //else if(!strcmp(command,"getenv"))printf("(0x%08X) get: '%s' = '%s'(0x%08X) \n",environ,token[1],getenv(token[1]),getenv(token[1])); + else if(!strcmp(command,"getenv"))printf("%s\n",getenv(token[1])); + else if(!strcmp(command,"setenv")) { - char *dir=getenv("PWD"); - - char buf[256]; - - if(token[1][0]!='/') - { - sprintf(buf,"%s%s%s",dir,dir[0]=='/'&&dir[1]==0?"":"/",token[1]); - } - else - { - sprintf(buf,"%s",token[1]); - } - - char token[10]; - - //adjust pwd (resolve '..' and '.') -//// printf("adjusting pwd: '%s'\n",buf); - int left=1; - int right=0; - - do{ - - int t=0; - do - { - right++; - token[t]=buf[right]; - - t++; - } - while(buf[right]!=0&&buf[right]!='/'); - token[t-1]=0; - -// printf("path token: '%s'\n",token); - - if(!strcmp(token,"..")) - { - left--; - while(buf[left]!='/')left--; - } - else if(!strcmp(token,".")) - { - } - else - { - int i=0; - if(left!=1)buf[left++]='/'; - do{buf[left++]=token[i++];}while(token[i]!=0); - } - - }while(buf[right]!=0); - buf[left]=0; -// printf("adjusted: '%s'\n",buf); - if(buf[0]==0)setenv("PWD","/",1); - else setenv("PWD",buf,1); - } - else if(!strcmp(command,"exit")) - { - _exit(1); - } - else if(!strcmp(command,"echo")) - { - printf("\"%s\"\n",token[1]); - - } - else if(!strcmp(command,"getenv")) - { - printf("(0x%08X) get: '%s' = '%s'(0x%08X) \n",environ,token[1],getenv(token[1]),getenv(token[1])); - } - else if(!strcmp(command,"putenv")||!strcmp(command,"setenv")) - { - char buf[256]; sprintf(buf,"%s=%s",token[1],token[2]); putenv(buf); - printf("(0x%08X) set: '%s' = '%s' \n",environ,token[1],getenv(token[1])); + //printf("(0x%08X) set: '%s' = '%s' \n",environ,token[1],getenv(token[1])); } else if(!strcmp(command,"env")) { int i=0; - printf("env: 0x%08X\n",environ); +// printf("env: 0x%08X\n",environ); while(environ[i]!=NULL) { - printf("envvar %s (0x%08X)\n" ,environ[i],environ[i]); +// printf("envvar %s (0x%08X)\n" ,environ[i],environ[i]); + printf("%s\n" ,environ[i]); i++; } } - else + else // otherwise treat command as exectutable and send to execve { int pid=_fork(); if(pid==0) { - sprintf(buf,"%s",token[0]); - _execve(buf,token,environ); - sprintf(buf,"%s/%s",getenv("PATH"),token[0]); + if(token[0][0]=='/')sprintf(buf,"%s",token[0]); + else sprintf(buf,"%s/%s",getenv("PATH"),token[0]); _execve(buf,token,environ); - puts("foolshell: command not found"); - exit(0); + printf("foolshell: %s (errno: %d)\n",strerror(errno),errno); + return false; } - if(token[1]==NULL||strcmp(token[1],"branch"))_wait(pid); + if(token[1]==NULL||strcmp(token[1],"&"))_wait(pid); } - return 0; + return true; +} + +bool setpwd(char *path) +{ + if(!strcmp(path,"/")) + { + putenv("PWD=/"); + return true; + } + char buf[255]; + buf[0]=0; + strcat(buf,"PWD="); + + char **t=tokenize(path,'/'); + + char *p[100]; + int pp=0; + + while(*t!=NULL) + { + if(!strcmp(*t,"..")){ + pp--; + t++; + if(pp<0)pp=0; + continue; + } + if(!strcmp(*t,".")){t++; continue;} + if(**t!=0) + { + p[pp]=*t; + //printf("> %s\n",p[pp]); + pp++; + } + t++; + } + + if(pp==0) + { + strcat(buf,"/"); + } + + for(int i=0;i<pp;i++) + { + strcat(buf,"/"); + strcat(buf,p[i]); + } + + putenv(buf); + return true; // TODO check if dir exists at all. +} + +bool cd(char *path) +{ + char buf[256]; + if(path==NULL)return setpwd(getenv("HOME")); + if(path[0]=='/')return setpwd(path); + sprintf(buf,"%s/%s",getenv("PWD"),path); + return setpwd(buf); } diff --git a/userspace/init.c b/userspace/init.c index 3384edb..8530368 100644 --- a/userspace/init.c +++ b/userspace/init.c @@ -4,7 +4,7 @@ int main(int argc, char **argv) { char *argv1[]={"/bin/foolshell",0}; - char *env1[]={"PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; + char *env1[]={"HOME=/home/miguel","PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; time_t ltime; time(<ime); |
