From 478c691187fbc9ba4ccaacf92f57828eef20041c Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Fri, 18 May 2012 19:06:35 +0200 Subject: Simple shell added. Simple fprintf function added too. --- Makefile | 7 +- menu_cdrom.lst | 4 +- src/include/tce/vfs.h | 2 +- src/kernel/core/kmain.cpp | 5 +- src/kernel/dev/keyboard.cpp | 2 +- src/kernel/task/task.cpp | 2 +- src/kernel/ui/vt.cpp | 14 ++- src/kernel/ui/vt.h | 4 +- src/kernel/vfs/node.cpp | 5 +- src/user/init/Makefile | 6 + src/user/init/main.c | 24 ++++ src/user/lib/include/stdarg.h | 10 ++ src/user/lib/include/stdio.h | 10 +- src/user/lib/std/stdio.c | 73 ++++++++++- src/user/lib/std/stdlib.c | 5 +- src/user/lib/std/string.c | 2 +- src/user/test/main.c | 93 +++----------- src/user/yosh/Makefile | 6 + src/user/yosh/main.c | 285 ++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 458 insertions(+), 101 deletions(-) create mode 100644 src/user/init/Makefile create mode 100644 src/user/init/main.c create mode 100644 src/user/lib/include/stdarg.h create mode 100644 src/user/yosh/Makefile create mode 100644 src/user/yosh/main.c diff --git a/Makefile b/Makefile index ab689c0..db4d827 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: clean, mrproper, Init.rfs, floppy, commit -Projects = tools/makeinitrd kernel user/lib user/test +Projects = tools/makeinitrd kernel user/lib user/init user/test user/yosh QemuCmd = qemu-system-i386 BasePath = $(shell pwd) @@ -36,7 +36,7 @@ commit: mrproper git commit -a; exit 0 git push origin -$(Cdrom): menu_cdrom.lst src/kernel/kernel.elf src/user/test/test.elf +$(Cdrom): menu_cdrom.lst src/kernel/kernel.elf src/user/test/test.elf src/user/init/init.elf src/user/yosh/yosh.elf mkdir -p cdrom/boot/grub if [ ! -e cdrom/boot/grub/stage2_eltorito ]; then \ echo "Please copy grub's stage2_eltorito to cdrom/boot/grub."; \ @@ -44,10 +44,11 @@ $(Cdrom): menu_cdrom.lst src/kernel/kernel.elf src/user/test/test.elf fi src/tools/makeinitrd/makeinitrd cdrom/initrd \ src/user/test/test.elf:/bin/test \ + src/user/yosh/yosh.elf:/bin/yosh \ README:/readme cp menu_cdrom.lst cdrom/boot/grub/menu.lst cp src/kernel/kernel.elf cdrom - cp src/user/test/test.elf cdrom + cp src/user/init/init.elf cdrom genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 \ -boot-info-table -input-charset ascii -A TCE -o $(Cdrom) cdrom diff --git a/menu_cdrom.lst b/menu_cdrom.lst index 4728398..b941b63 100644 --- a/menu_cdrom.lst +++ b/menu_cdrom.lst @@ -2,5 +2,5 @@ timeout 10 title T/CE kernel /kernel.elf -module /initrd somewhere -module /test.elf arg +module /initrd +module /init.elf /initrd/bin/test /initrd/bin/yosh diff --git a/src/include/tce/vfs.h b/src/include/tce/vfs.h index 20ea03b..00c80d7 100644 --- a/src/include/tce/vfs.h +++ b/src/include/tce/vfs.h @@ -3,7 +3,7 @@ #include -typedef size_t FILE; +typedef int FILE; typedef struct _file_info { uint32_t type; diff --git a/src/kernel/core/kmain.cpp b/src/kernel/core/kmain.cpp index 96c4050..0aa047a 100644 --- a/src/kernel/core/kmain.cpp +++ b/src/kernel/core/kmain.cpp @@ -55,9 +55,12 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { // Init display devices text_display = new vgatxt(dot_dev); dot_dev->add_child("vgatxt", text_display); - ke_vt = new vt(dot_dev, 80, 25); + + ke_vt = new vt(dot_ui, 80, 25); dot_ui->add_child("klog", ke_vt); ke_vt->outputTo(text_display); + home_vt = new vt(dot_ui, 80, 25); + dot_ui->add_child("home", home_vt); // Say hello ke_vt->fgcolor = TC_LIGHTGRAY; diff --git a/src/kernel/dev/keyboard.cpp b/src/kernel/dev/keyboard.cpp index ce8e77b..3f54b99 100644 --- a/src/kernel/dev/keyboard.cpp +++ b/src/kernel/dev/keyboard.cpp @@ -150,7 +150,7 @@ void keyboard::handle(int scancode, bool pressed) { // process keypress if (output != 0) { - output->keyboardInput(kp); + output->keyboardInput(kp, this); } else { // TODO: enable reading directly keypresses from keyboard device } diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp index 02294bd..98204d6 100644 --- a/src/kernel/task/task.cpp +++ b/src/kernel/task/task.cpp @@ -119,7 +119,7 @@ uint32_t tasking_handleException(registers *regs) { if (regs->eip >= K_HIGHHALF_ADDR) { *ke_vt << "\nException in kernel. Stack trace:\n"; stack_trace(regs->ebp); - } + } if (regs->int_no == 14) { *ke_vt << "\n>>> Process exiting.\n"; thread_exit_stackJmp(EX_PR_EXCEPTION); diff --git a/src/kernel/ui/vt.cpp b/src/kernel/ui/vt.cpp index 2869fec..2bd82ca 100644 --- a/src/kernel/ui/vt.cpp +++ b/src/kernel/ui/vt.cpp @@ -1,7 +1,7 @@ #include "vt.h" #include -vt *ke_vt = 0; +vt *ke_vt = 0, *home_vt = 0; vt::vt(node* parent, int ww, int hh) : node(parent, FT_TERMINAL) { w = ww; h = hh; @@ -9,6 +9,7 @@ vt::vt(node* parent, int ww, int hh) : node(parent, FT_TERMINAL) { bgcolor = TC_BLACK; output = 0; cursor_visible = true; + csr_l = csr_c = 0; kbd_buffer_filled = 0; kbd_waiter = 0; @@ -148,9 +149,18 @@ void vt::outputTo(display *display) { } } } + output->text_setcsr(csr_l, csr_c, cursor_visible); } -void vt::keyboardInput(keypress kp) { +void vt::keyboardInput(keypress kp, keyboard* from) { + if (kp.command == KB_RSUPER || kp.command == KB_LSUPER) { + if (this == home_vt) return; + // go to home terminal + home_vt->outputTo(output); + from->outputTo(home_vt); + output = 0; + return; + } // convert to sequence of chars int n = 0; char b[8]; diff --git a/src/kernel/ui/vt.h b/src/kernel/ui/vt.h index b26e95a..a80452b 100644 --- a/src/kernel/ui/vt.h +++ b/src/kernel/ui/vt.h @@ -45,7 +45,7 @@ class vt : public node { void outputTo(display *display); - void keyboardInput(keypress kp); + void keyboardInput(keypress kp, keyboard* from); virtual int write(size_t offset, size_t len, char* buffer); virtual int read(size_t offset, size_t len, char* buffer); // get keyboard input @@ -53,7 +53,7 @@ class vt : public node { virtual int link(node* to, int mode); }; -extern vt *ke_vt; +extern vt *ke_vt, *home_vt; #define NL ke_vt->writeStr("\n"); #define TAB ke_vt->writeStr("\t"); #define WHERE { ke_vt->writeStr("(ke:"); \ diff --git a/src/kernel/vfs/node.cpp b/src/kernel/vfs/node.cpp index ea7b531..c517aae 100644 --- a/src/kernel/vfs/node.cpp +++ b/src/kernel/vfs/node.cpp @@ -27,8 +27,7 @@ void vfs_setup() { node* vfs_find(node* root, char* fn) { node* el = root; - char *path = strdup(fn); - char *s = path; + char *path = fn; char *member = path; while (*path != 0 && el != 0) { @@ -39,6 +38,7 @@ node* vfs_find(node* root, char* fn) { } else { *path = 0; el = el->get_child(member); + *path = '/'; path++; member = path; } @@ -49,7 +49,6 @@ node* vfs_find(node* root, char* fn) { if (el != 0 && member != path) { el = el->get_child(member); } - kfree(s); return el; } diff --git a/src/user/init/Makefile b/src/user/init/Makefile new file mode 100644 index 0000000..286de06 --- /dev/null +++ b/src/user/init/Makefile @@ -0,0 +1,6 @@ +Obj = main.o +Out = init.elf + +include $(SrcPath)/user/app_common.make + +LDFLAGS += -Map test.map diff --git a/src/user/init/main.c b/src/user/init/main.c new file mode 100644 index 0000000..7d4ea0e --- /dev/null +++ b/src/user/init/main.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(char** args) { + int i; + + FILE term = open("/.ui/klog", 0); + if (term <= 0) return -1; + + fprint(term, "(init) Trivial/Computing Environment says hello. Press super to go home.\n"); + + for (i = 0; args[i] != 0; i++) { + if (i == 0) continue; + fprintf(term, "(init) Spawning %s...\n", args[i]); + int pid = run(args[i], 0); + if (pid < 0) { + fprint(term, "(init) Error. Sorry.\n"); + } else { + waitpid(pid); + } + } + fprint(term, "(init) Goodbye.\n"); +} diff --git a/src/user/lib/include/stdarg.h b/src/user/lib/include/stdarg.h new file mode 100644 index 0000000..5cd74ff --- /dev/null +++ b/src/user/lib/include/stdarg.h @@ -0,0 +1,10 @@ +#ifndef DEF_STDARG_H +#define DEF_STDARG_H + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_arg(v,l) __builtin_va_arg(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_copy(d,s) __builtin_va_copy(d,s) +typedef __builtin_va_list va_list; + +#endif diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h index e3f9d89..91fe169 100644 --- a/src/user/lib/include/stdio.h +++ b/src/user/lib/include/stdio.h @@ -1,7 +1,13 @@ #ifndef DEF_STDIO_H #define DEF_STDIO_H -void printk_int(int number); -void printk_hex(unsigned number); +#include + +void fprint(FILE f, char *s); +void fprint_int(FILE f, int number); +void fprint_hex(FILE f, unsigned number); +void fprintf(FILE f, char *s, ...); + +char* freadln(FILE f); #endif diff --git a/src/user/lib/std/stdio.c b/src/user/lib/std/stdio.c index c11dd05..2bce2e3 100644 --- a/src/user/lib/std/stdio.c +++ b/src/user/lib/std/stdio.c @@ -1,9 +1,14 @@ #include #include +#include -void printk_int(int number) { +void fprint(FILE f, char *s) { + write(f, 0, strlen(s), s); +} + +void fprint_int(FILE f, int number) { if (number == 0) { - printk("0"); + fprint(f, "0"); return; } int negative = 0; @@ -31,10 +36,10 @@ void printk_int(int number) { number /= 10; } r[order] = 0; - printk(s); + fprint(f, s); } -void printk_hex(unsigned v) { +void fprint_hex(FILE f, unsigned v) { char s[11] = {'0', 'x', 0}; int i; @@ -46,5 +51,63 @@ void printk_hex(unsigned v) { v = v << 4; } s[11] = 0; - printk(s); + fprint(f, s); +} + +void fprintf(FILE f, char* format, ...) { + va_list ap; + va_start(ap, format); + + char* start = format; + + while (*format) { + if (*format == '%') { + if (start != format) write(f, 0, format - start, start); + format++; + if (*format == 'd' || *format == 'i') { + fprint_int(f, va_arg(ap, int)); + } else if (*format == 'p') { + fprint_hex(f, va_arg(ap, uint32_t)); + } else if (*format == 's') { + fprint(f, va_arg(ap, char*)); + } + format++; + start = format; + } else { + format++; + } + } + if (start != format) write(f, 0, format - start, start); + + va_end(ap); +} + +char* freadln(FILE f) { + int i; + + char *p = (char*)malloc(256); + char *b = p; + + while (1) { + int l = read(f, 0, 255, b); + if (l < 0) { + free(b); + return 0; + } + + for (i = 0; i < l; i++) { + if (b[i] == '\n') { + b[i+1] = 0; + return p; + } + } + + int d = b - p + l; + + char* newp = (char*)malloc(d + 256); + memcpy(newp, p, d); + free(p); + p = newp; + b = p + d; + } } diff --git a/src/user/lib/std/stdlib.c b/src/user/lib/std/stdlib.c index 21753e9..9d46b5c 100644 --- a/src/user/lib/std/stdlib.c +++ b/src/user/lib/std/stdlib.c @@ -4,8 +4,5 @@ volatile int errno; void abort() { - printk("Abort - errno "); - printk_int(errno); - printk(".\n"); - process_exit(-1); + process_exit(100 + errno); } diff --git a/src/user/lib/std/string.c b/src/user/lib/std/string.c index 20fd9e8..7cd8ede 100644 --- a/src/user/lib/std/string.c +++ b/src/user/lib/std/string.c @@ -3,7 +3,7 @@ int strlen(const char *str) { int i = 0; while (str[i++]); - return i; + return i-1; } char *strchr(const char *str, char c) { diff --git a/src/user/test/main.c b/src/user/test/main.c index eb289ca..411cc71 100644 --- a/src/user/test/main.c +++ b/src/user/test/main.c @@ -4,6 +4,8 @@ int threads = 0; +FILE out = 0; + void thread_cascade(void* d) { int n = (int)d; @@ -45,30 +47,30 @@ void list_dir(FILE f, int lv) { i++; continue; } - for (k = 0; k < lv; k++) printk(" "); - printk(buf); + for (k = 0; k < lv; k++) fprint(out, " "); + fprint(out, buf); stat_relative(f, buf, &info); - if (info.type & FT_DIR) printk("/"); - printk(" \t"); + if (info.type & FT_DIR) fprint(out, "/"); + fprint(out, " \t"); - if (info.type & FT_FILE) printk("file "); - if (info.type & FT_DIR) printk("dir "); - if (info.type & FT_SYMLINK) printk("symlink "); - if (info.type & FT_DEV) printk("dev "); - if (info.type & FT_TERMINAL) printk("term "); + if (info.type & FT_FILE) fprint(out, "file "); + if (info.type & FT_DIR) fprint(out, "dir "); + if (info.type & FT_SYMLINK) fprint(out, "symlink "); + if (info.type & FT_DEV) fprint(out, "dev "); + if (info.type & FT_TERMINAL) fprint(out, "term "); if (info.type & FT_DIR) { - printk(" \t"); + fprint(out, " \t"); FILE ff = open_relative(f, buf, 0); if (ff <= 0) { - printk("error: "); printk_int(ff); printk("\n"); + fprintf(out, "error: %i\n", ff); } else { - printk("fd: "); printk_int(ff); printk("\n"); + fprintf(out, "fd: %i\n", ff); list_dir(ff, lv+1); close(ff); } } else { - printk("\n"); + fprint(out, "\n"); } i++; } @@ -77,20 +79,14 @@ void list_dir(FILE f, int lv) { void list_root() { FILE f = open("/", 0); if (f <= 0) { - printk(" -> Could not open '/', error #"); - printk_int(f); - printk("...\n"); + fprintf(out, " -> Could not open '/', error #%i\n", f); } else { - printk("Now enumerating '/' (fd "); printk_int(f); printk(") :\n"); + fprintf(out, "Now enumerating '/' (fd %i) :\n", f); list_dir(f, 1); close(f); } } -void fprint(FILE f, char *s) { - write(f, 0, strlen(s), s); -} - int main(char** args) { char**a; if (args != 0) { @@ -102,66 +98,17 @@ int main(char** args) { printk("\n"); } - printk("(test app) malloc(42) = "); - printk_hex((uint32_t)malloc(42)); - printk("\n"); - printk(" -> Creating thread cascade (total 2**4 = 16 threads)\n"); thread_new(thread_cascade, (void*)4); - printk(" -> Main thread now sleeping...\n"); while (1) { thread_sleep(100); if (threads == 0) break; } - printk("\n -> Ok, let's try something else.\n"); - list_root(); - - FILE f = open("/.ui/klog", 0); - if (f <= 0) { - printk(" -> Error #"); printk_int(f); printk(" - too bad. Exiting.\n"); - } else { - fprint(f, " -> Now reading && writing from/to virtual terminal '/.ui/klog'\n"); - while (1) { - fprint(f, " > "); - - char buffer[256]; - int l = read(f, 0, 255, buffer); - buffer[l] = 0; - if (buffer[l-1] == '\n') { - buffer[l-1] = 0; l--; + printk("\n"); - if (strcmp(buffer, "about") == 0) { - fprint(f, "Trivial/Computing Environment v0.1.0 - useless shell, first ediiton.\n"); - } else if (strcmp(buffer, "help") == 0) { - fprint(f, "Available commands: about, help, exit.\n"); - } else if (strcmp(buffer, "exit") == 0) { - fprint(f, "Exiting the shell. See you later!\n"); - break; - } else if (strcmp(buffer, "gotosleep") == 0) { - while (1) thread_sleep(1000); - } else if (strcmp(buffer, "spawn") == 0) { - char *args[] = {"hello", "world", 0}; - int pid = run("/somewhere/bin/test", args); - if (pid < 0) { - printk("Error "); printk_int(pid); printk("\n"); - } else { - printk("Launched, pid="); printk_int(pid); printk("\n"); - int ret = waitpid(pid); - printk("Exited, ret="); printk_int(ret); printk("\n"); - } - } else if (strcmp(buffer, "root") == 0) { - list_root(); - } else { - fprint(f, "Unknown command : "); - fprint(f, buffer); - fprint(f, "\n"); - } - } else { - fprint(f, " - - - oops\n"); - } - } - } + out = open("/.ui/klog", 0); + list_root(); return 0; } diff --git a/src/user/yosh/Makefile b/src/user/yosh/Makefile new file mode 100644 index 0000000..9879a73 --- /dev/null +++ b/src/user/yosh/Makefile @@ -0,0 +1,6 @@ +Obj = main.o +Out = yosh.elf + +include $(SrcPath)/user/app_common.make + +LDFLAGS += -Map test.map diff --git a/src/user/yosh/main.c b/src/user/yosh/main.c new file mode 100644 index 0000000..957060e --- /dev/null +++ b/src/user/yosh/main.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include + +FILE out, cwd_f; +char *cwd; + +void about() { + fprint(out, "Trivial/Computing Environment v0.1.0 - yosh 2.\n"); +} + +void help(char *args[]) { + if (args[1] == 0) { + fprint(out, "Available commands: about, help, exit, ls, cd, switch.\n"); + } else if (strcmp(args[1], "about") == 0) { + fprint(out, "Usage:\tabout\nShows some info about yosh. Very usefull.\n"); + } else if (strcmp(args[1], "help") == 0) { + fprint(out, "Usage:\thelp\n\thelp \n"); + fprint(out, "Shows some info about the command you want, or commands in general.\n"); + } else if (strcmp(args[1], "exit") == 0) { + fprint(out, "Usage:\texit\n"); + fprint(out, "Exits the shell.\nWill probably make your system panic if you only have a shell running.\n"); + } else if (strcmp(args[1], "cd") == 0) { + fprint(out, "Usage:\tcd \nGoes to the location specified.\n"); + } else if (strcmp(args[1], "ls") == 0) { + fprint(out, "Usage:\tls\n\tls ...\nShows the content of the current/specified directory.\n"); + } else if (strcmp(args[1], "switch") == 0) { + fprint(out, "Usage:\tswitch \nSwitchs focus to specified virtual terminal.\n"); + fprint(out, "Type `ls /.ui` to see available terminals.\n"); + } else { + fprintf(out, "No such command: %s\n", args[1]); + } +} + +void simplify_path(char* p) { + char *it = p; + char *member = it; + while (*it != 0) { + if (*it == '/') { + if (it == member && it != p) { + // two consecutive slashes + char *i = member; + while (1) { + i[0] = i[1]; + if (i[0] == 0) break; + i++; + } + } else { + *it = 0; + if (strcmp(member, ".") == 0) { + char *i = member; + while (1) { + i[0] = i[2]; + if (i[0] == 0) break; + i++; + } + } else if (strcmp(member, "..") == 0) { + *it = '/'; + char* start = member - 2; + char* next = member + 3; + while (start > p && *start != '/') { + start--; + } + start++; + it = member = start; + while (1) { + *start = *next; + if (*start == 0) break; + start++; + next++; + } + } else { + *it = '/'; + it++; + member = it; + } + } + } else { + it++; + } + } +} + +char* path_cat (char* a, char* b) { + char* ret; + if (b[0] == '/') { + int lb = strlen(b); + ret = (char*)malloc(lb + 2); + memcpy(ret, b, lb); + if (ret[lb - 1] != '/') { + ret[lb] = '/'; + lb++; + } + ret[lb] = 0; + } else { + int la = strlen(a); + int lb = strlen(b); + + ret = (char*)malloc(la + lb + 2); + memcpy(ret, a, la); + memcpy(ret + la, b, lb); + if (ret[la + lb - 1] != '/') { + ret[la + lb] = '/'; + lb++; + } + ret[la + lb] = 0; + } + simplify_path(ret); + return ret; +} + +void cd(char **args) { + if (args[1] == 0) { + fprint(out, "Usage: cd \n"); + } + if (strcmp(args[1], ".") == 0) return; + + char* newcwd = path_cat(cwd, args[1]); + + file_info info; + int i = stat(newcwd, &info); + if (i == E_NOT_FOUND) { + fprint(out, "No such file or directory.\n"); + free(newcwd); + } else if (i < 0) { + fprintf(out, "Error stating: %i\n", i); + free(newcwd); + } else if ((info.type & FT_DIR) == 0) { + fprint(out, "Not a directory.\n"); + free(newcwd); + } else { + FILE nf = open(newcwd, 0); + if (nf <= 0) { + fprintf(out, "Error opening: %i\n", nf); + free(newcwd); + } else { + free(cwd); + cwd = newcwd; + close(cwd_f); + cwd_f = nf; + } + } +} + +void ls_dir(FILE f) { + file_info info; + int i = 0; + char buf[256]; + while (read(f, i, 256, buf) > 0) { + i++; + + if (strcmp(buf, ".") == 0 || strcmp(buf, "..") == 0) continue; + + fprintf(out, " %s", buf); + + stat_relative(f, buf, &info); + if (info.type & FT_DIR) fprint(out, "/"); + fprint(out, " \t"); + + if (info.type & FT_FILE) fprint(out, "file "); + if (info.type & FT_DIR) fprint(out, "dir "); + if (info.type & FT_SYMLINK) fprint(out, "symlink "); + if (info.type & FT_DEV) fprint(out, "dev "); + if (info.type & FT_TERMINAL) fprint(out, "term "); + + fprint(out, "\t"); + if (info.type & FT_TERMINAL) { + fprintf(out, "%ix%i", info.size >> 16, info.size & 0xFFFF); + } else if ((info.type & FT_DEV) == 0) { + fprintf(out, "%i", info.size); + } + + fprint(out, "\n"); + } +} + +void ls(char **args) { + if (args[1] == 0) { + ls_dir(cwd_f); + } else { + int i; + for (i = 1; args[i] != 0; i++) { + fprintf(out, "Contents of %s :\n", args[i]); + char* d = path_cat(cwd, args[i]); + file_info info; + int e = stat(d, &info); + if (e == E_NOT_FOUND) { + fprint(out, " No such file or directory\n"); + } else if (e < 0) { + fprintf(out, " Error stating: %i\n", e); + } else { + FILE ff = open(d, 0); + if (ff <= 0) { + fprintf(out, " Error opening: %i\n", ff); + } else { + ls_dir(ff); + close(ff); + } + } + free(d); + } + } +} + +void t_switch(char** args) { + if (args[1] == 0) { + fprint(out, "Usage: switch \n"); + return; + } + char* p = path_cat("/.ui/", args[1]); + int i; + if ((i = link(p, "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) { + link("/.dev/ps2kbd", p, LM_OUTPUT_TO); + } else { + fprintf(out, "Error %i\n", i); + } +} + +int main(char **sh_args) { + out = open("/.ui/home", 0); + if (out <= 0) { + return -1; + } + + about(); + + cwd = strdup("/"); + cwd_f = open(cwd, 0); + + while (1) { + fprintf(out, " %s ", cwd); + + char *s = freadln(out); + if (s == 0) return -1; + int l = strlen(s); + if (s[l-1] == '\n') { + s[l-1] = 0; l--; + + char *c_args[16] = {0}, *cmd; + c_args[0] = s; + int argc = 1; + for (cmd = s; *cmd != 0; cmd++) { + if (*cmd == ' ') { + *cmd = 0; + if (cmd[1] != ' ' && cmd[1] != 0) { + c_args[argc] = cmd + 1; + argc++; + if (argc == 15) break; + } + } + } + + if (strcmp(c_args[0], "about") == 0) { + about(); + } else if (strcmp(c_args[0], "help") == 0) { + help(c_args); + } else if (strcmp(c_args[0], "exit") == 0) { + fprint(out, "Exiting the shell. See you later!\n"); + break; + } else if (strcmp(c_args[0], "cd") == 0) { + cd(c_args); + } else if (strcmp(c_args[0], "ls") == 0) { + ls(c_args); + } else if (strcmp(c_args[0], "switch") == 0) { + t_switch(c_args); + } else { + char *c = path_cat(cwd, c_args[0]); + int pid = run(c, c_args + 1); + if (pid <= 0) { + fprintf(out, "Error %i\n", pid); + } else { + int ret = waitpid(pid); + fprintf(out, "Exited with status %i\n", ret); + } + free(c); + } + } else { + fprint(out, "[freadln fail, sorry.]\n"); + } + free(s); + } + + return 0; +} -- cgit v1.2.3