From d502fce7d4db492690e39c72fc029aa05a65057d Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Sat, 19 May 2012 16:38:56 +0200 Subject: More improvements in FWIK - more strings, Dir class, ... --- src/include/tce/syscalls.h | 1 + src/kernel/task/task.cpp | 3 +- src/user/app/test/main.c | 4 +- src/user/app/yosh/main.cpp | 94 ++++++++++++++++-------------------- src/user/lib/fwik/Makefile | 2 +- src/user/lib/fwik/include/IO/Dir.h | 24 +++++++++ src/user/lib/fwik/include/IO/Node.h | 5 +- src/user/lib/fwik/io/Dir.cpp | 37 ++++++++++++++ src/user/lib/fwik/io/Node.cpp | 24 ++++++--- src/user/lib/fwik/io/Term.cpp | 12 ++++- src/user/lib/libc/include/readline.h | 1 + src/user/lib/libc/include/stdio.h | 1 - src/user/lib/libc/std/readline.c | 4 ++ src/user/lib/libc/std/stdio.c | 6 ++- 14 files changed, 149 insertions(+), 69 deletions(-) create mode 100644 src/user/lib/fwik/include/IO/Dir.h create mode 100644 src/user/lib/fwik/io/Dir.cpp diff --git a/src/include/tce/syscalls.h b/src/include/tce/syscalls.h index 76a5ba2..c82cab7 100644 --- a/src/include/tce/syscalls.h +++ b/src/include/tce/syscalls.h @@ -38,5 +38,6 @@ #define E_INVALID_RANGE -5 #define E_INVALID -6 // anything went wrong - invalid parameter, usually #define E_NOT_FINISHED -7 // nonblocking waitpid on process that hasn't finished +#define E_INVALID_TYPE -8 // incorrect node type #endif diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp index 03425b5..5dea33b 100644 --- a/src/kernel/task/task.cpp +++ b/src/kernel/task/task.cpp @@ -68,7 +68,6 @@ void tasking_updateKernelPagetable(uint32_t idx, page_table *table, uint32_t tab /* Called when a timer IRQ fires. Does a context switch. */ void schedule() { - //if (processes == 0) PANIC("No processes are running !"); asm volatile("cli"); uint32_t esp, ebp, eip; @@ -205,6 +204,7 @@ void process_exit(size_t retval) { (its address is the value given for EIP). It switches to user mode if necessary and calls the entry point. */ static void thread_run(void* u_esp, thread *thread, thread_entry entry_point, void *data) { + asm volatile("cli"); pagedir_switch(thread->process->pagedir); if (thread->process->privilege >= PL_USER) { //User mode ! uint32_t *stack = (uint32_t*)u_esp; @@ -237,6 +237,7 @@ static void thread_run(void* u_esp, thread *thread, thread_entry entry_point, vo push %%eax; \ pushl $0x1B; \ push %%ecx; \ + sti; \ iret; \ " : : "b"(esp), "c"(eip)); } else { diff --git a/src/user/app/test/main.c b/src/user/app/test/main.c index e691d6f..d235c57 100644 --- a/src/user/app/test/main.c +++ b/src/user/app/test/main.c @@ -43,8 +43,8 @@ int main(char** args) { printk("\n"); } - printk("(test) Creating thread cascade (total 2**6 = 64 threads)\n"); - thread_new(thread_cascade, (void*)6); + printk("(test) Creating thread cascade (total 2**5 = 32 threads)\n"); + thread_new(thread_cascade, (void*)5); while (1) { thread_sleep(100); diff --git a/src/user/app/yosh/main.cpp b/src/user/app/yosh/main.cpp index 37b557d..fc9580c 100644 --- a/src/user/app/yosh/main.cpp +++ b/src/user/app/yosh/main.cpp @@ -4,8 +4,9 @@ #include #include #include +#include -FILE cwd_f; +Dir *cwd_f; String cwd; void about() { @@ -43,52 +44,46 @@ void cd(String *args) { String newcwd = path_cat(cwd, args[1]); - file_info info; - int i = libc::stat(newcwd.c_str(), &info); - if (i == E_NOT_FOUND) { + Dir *newdir = new Dir(newcwd.c_str(), 0); + if (newdir->error == E_NOT_FOUND) { stdio << "No such file or directory.\n"; - } else if (i < 0) { - stdio.printf("Error stating: %i\n", i); - } else if ((info.type & FT_DIR) == 0) { + } else if (newdir->error == E_INVALID_TYPE) { stdio << "Not a directory.\n"; + } else if (newdir->error != 0) { + stdio.printf("Error stating: %i\n", newdir->error); } else { - FILE nf = libc::open(newcwd.c_str(), 0); - if (nf < 0) { - stdio.printf("Error opening: %i\n", nf); - } else { - cwd = newcwd; - libc::close(cwd_f); - cwd_f = nf; - } + cwd_f->close(); + cwd = newcwd; + cwd_f = newdir; } } -void ls_dir(FILE f) { - file_info info; - int i = 0; - char buf[256]; - while (libc::read(f, i, 256, buf) > 0) { - i++; +void ls_dir(Dir *d) { + if (d->error != 0) { + return; + } + d->pos = 0; + for (String name = d->read_ent(); name; name = d->read_ent()) { + if (name == "." || name == "..") continue; - if (libc::strcmp(buf, ".") == 0 || libc::strcmp(buf, "..") == 0) continue; + stdio.printf(" %s", name.c_str()); - stdio.printf(" %s", buf); + Node child(d->fd, name.c_str(), 0); - libc::stat_relative(f, buf, &info); - if (info.type & FT_DIR) stdio << "/"; + if (child.info.type & FT_DIR) stdio << "/"; stdio << " \t"; - if (info.type & FT_FILE) stdio << "file "; - if (info.type & FT_DIR) stdio << "dir "; - if (info.type & FT_SYMLINK) stdio << "symlink "; - if (info.type & FT_DEV) stdio << "dev "; - if (info.type & FT_TERMINAL) stdio << "term "; + if (child.info.type & FT_FILE) stdio << "file "; + if (child.info.type & FT_DIR) stdio << "dir "; + if (child.info.type & FT_SYMLINK) stdio << "symlink "; + if (child.info.type & FT_DEV) stdio << "dev "; + if (child.info.type & FT_TERMINAL) stdio << "term "; stdio << "\t"; - if (info.type & FT_TERMINAL) { - stdio.printf("%ix%i", info.size >> 16, info.size & 0xFFFF); - } else if ((info.type & FT_DEV) == 0) { - stdio.printf("%i", info.size); + if (child.info.type & FT_TERMINAL) { + stdio.printf("%ix%i", child.info.size >> 16, child.info.size & 0xFFFF); + } else if ((child.info.type & FT_DEV) == 0) { + stdio.printf("%i", child.info.size); } stdio << "\n"; @@ -103,22 +98,16 @@ void ls(String *args) { for (i = 1; args[i]; i++) { stdio.printf("Contents of %s :\n", args[i].c_str()); String d = path_cat(cwd, args[i].c_str()); - file_info info; - int e = libc::stat(d.c_str(), &info); - if (e == E_NOT_FOUND) { + Dir dir(d.c_str(), 0); + if (dir.error == E_NOT_FOUND) { stdio << " No such file or directory\n"; - } else if (e < 0) { - stdio.printf(" Error stating: %i\n", e); - } else if ((info.type & FT_DIR) == 0) { + } else if (dir.error == E_INVALID_TYPE) { stdio.printf(" Not a directory.\n"); + } else if (dir.error < 0) { + stdio.printf(" Error stating: %i\n", dir.error); } else { - FILE ff = libc::open(d.c_str(), 0); - if (ff < 0) { - stdio.printf(" Error opening: %i\n", ff); - } else { - ls_dir(ff); - libc::close(ff); - } + ls_dir(&dir); + dir.close(); } } } @@ -165,7 +154,7 @@ int Main(String *sh_args) { about(); cwd = "/"; - cwd_f = libc::open(cwd.c_str(), 0); + cwd_f = new Dir("/", 0); String path = path_cat(sh_args[0], ".."); @@ -219,7 +208,7 @@ int Main(String *sh_args) { cat(c_args); } else { FILE vt = term->fd; - String *first_arg = c_args + 1; + String *first_arg = c_args ; String t; if (c_args[0] == "on") { @@ -237,11 +226,12 @@ int Main(String *sh_args) { } String c; - if (libc::strchr(c_args[0].c_str(), '/')) { - c = path_cat(cwd, c_args[0], false); + if (libc::strchr(first_arg->c_str(), '/')) { + c = path_cat(cwd, *first_arg, false); } else { - c = path_cat(path, c_args[0], false); + c = path_cat(path, *first_arg, false); } + first_arg++; const char *run_args[15] = {0}; for (int i = 0; first_arg[i]; i++) run_args[i] = first_arg[i].c_str(); diff --git a/src/user/lib/fwik/Makefile b/src/user/lib/fwik/Makefile index cf8896a..c99b288 100644 --- a/src/user/lib/fwik/Makefile +++ b/src/user/lib/fwik/Makefile @@ -1,5 +1,5 @@ Out = _fwik.o -Obj = String.o io/Node.o io/Term.o io/IOStream.o main.o +Obj = String.o io/Node.o io/Term.o io/Dir.o io/IOStream.o main.o ExtObj = $(SrcPath)/user/lib/libc/_libc.o diff --git a/src/user/lib/fwik/include/IO/Dir.h b/src/user/lib/fwik/include/IO/Dir.h new file mode 100644 index 0000000..bbfe3ed --- /dev/null +++ b/src/user/lib/fwik/include/IO/Dir.h @@ -0,0 +1,24 @@ +#ifndef DEF_FWIK_IO_DIR_H +#define DEF_FWIK_IO_DIR_H + +#include "Node.h" +#include + +class Dir : public Node { + void _init(); + + public: + int pos; + + Dir(FILE f); + Dir(const char* file, int mode); + Dir(const Node &n); + virtual ~Dir(); + + String read_ent(); + + virtual Dir* as_dir() { return this; } +}; + +#endif + diff --git a/src/user/lib/fwik/include/IO/Node.h b/src/user/lib/fwik/include/IO/Node.h index ed8290f..6b5b063 100644 --- a/src/user/lib/fwik/include/IO/Node.h +++ b/src/user/lib/fwik/include/IO/Node.h @@ -9,19 +9,22 @@ #include class Term; +class Dir; class Node { public: FILE fd; file_info info; - bool valid; + int error; // will be 0 if this is a valid file descriptor Node(FILE f); Node(const char* filename, int mode); + Node(FILE parent, const char* filename, int mode); virtual ~Node() {} void close(); virtual Term* as_term() { return 0; } + virtual Dir* as_dir() { return 0; } }; String path_cat(const String &a, const String &b, bool trailing_slash = true); diff --git a/src/user/lib/fwik/io/Dir.cpp b/src/user/lib/fwik/io/Dir.cpp new file mode 100644 index 0000000..cfcc77b --- /dev/null +++ b/src/user/lib/fwik/io/Dir.cpp @@ -0,0 +1,37 @@ +#include + +Dir::Dir(const Node &n) : Node(n) { + _init(); +} + +Dir::Dir(FILE f) : Node(f) { + _init(); + if (error == E_INVALID_TYPE) libc::close(fd); +} + +Dir::Dir(const char* filename, int mode) : Node(filename, mode) { + _init(); + if (error == E_INVALID_TYPE) libc::close(fd); +} + +void Dir::_init() { + if (error < 0) return; + pos = 0; + if ((info.type & FT_DIR) == 0) { + error = E_INVALID_TYPE; + } +} + +Dir::~Dir() { +} + +String Dir::read_ent() { + char buf[256]; + int l = libc::read(fd, pos, 256, buf); + if (l > 0) { + pos++; + return String(buf, l); + } else { + return ""; + } +} diff --git a/src/user/lib/fwik/io/Node.cpp b/src/user/lib/fwik/io/Node.cpp index daccc18..5585aa8 100644 --- a/src/user/lib/fwik/io/Node.cpp +++ b/src/user/lib/fwik/io/Node.cpp @@ -2,24 +2,34 @@ Node::Node(FILE f) { fd = f; - int i = libc::statf(f, &info); - valid = (i == 0); + error = libc::statf(f, &info); } Node::Node(const char* filename, int mode) { fd = libc::open(filename, mode); if (fd < 0) { - valid = false; + if (fd != E_NOT_FOUND) error = libc::stat(filename, &info); } else { int i = libc::statf(fd, &info); - valid = (i == 0); - if (!valid) libc::close(fd); + error = i; + if (error < 0) libc::close(fd); + } +} + +Node::Node(FILE parent, const char* filename, int mode) { + fd = libc::open_relative(parent, filename, mode); + if (fd < 0) { + if (fd != E_NOT_FOUND) error = libc::stat_relative(parent, filename, &info); + } else { + int i = libc::statf(fd, &info); + error = i; + if (error < 0) libc::close(fd); } } void Node::close() { - if (valid) libc::close(fd); - valid = false; + if (error == 0) libc::close(fd); + error = E_INVALID_FD; } //////// diff --git a/src/user/lib/fwik/io/Term.cpp b/src/user/lib/fwik/io/Term.cpp index 1540b9a..f8f686e 100644 --- a/src/user/lib/fwik/io/Term.cpp +++ b/src/user/lib/fwik/io/Term.cpp @@ -6,25 +6,33 @@ Term::Term(const Node &n) : Node(n) { Term::Term(FILE f) : Node(f) { _init(); + if (error E_INVALID_TYPE) libc::close(fd); } Term::Term(const char* filename, int mode) : Node(filename, mode) { _init(); + if (error == E_INVALID_TYPE) libc::close(fd); } void Term::_init() { + if (error < 0) return; if (info.type & FT_TERMINAL) { w = info.size >> 16; h = info.size & 0xFFFF; } else { - valid = false; + error = E_INVALID_TYPE; } hist.str = 0; hist.max = 12; } Term::~Term() { - //TODO : free readline history + if (hist.str != 0) { + for (int i = 0; i < hist.max; i++) { + if (hist.str[i] != 0) free(hist.str[i]); + } + free(hist.str); + } } void Term::print(const char *s) { diff --git a/src/user/lib/libc/include/readline.h b/src/user/lib/libc/include/readline.h index 910ad9a..1ec5baa 100644 --- a/src/user/lib/libc/include/readline.h +++ b/src/user/lib/libc/include/readline.h @@ -13,6 +13,7 @@ typedef struct _rdln_hist { #ifdef __cplusplus extern "C" { namespace libc { #endif +char *readln(); char* freadln(FILE f); // minimal line-reading function. user must free the returned value. char* freadline(FILE f, readline_history *h); #ifdef __cplusplus diff --git a/src/user/lib/libc/include/stdio.h b/src/user/lib/libc/include/stdio.h index f19ce60..72d355a 100644 --- a/src/user/lib/libc/include/stdio.h +++ b/src/user/lib/libc/include/stdio.h @@ -12,7 +12,6 @@ extern FILE term; void print(const char *s); void printf(const char *s, ...); -char *readln(); void fprint(FILE f, const char *s); void fprintf(FILE f, const char *s, ...); diff --git a/src/user/lib/libc/std/readline.c b/src/user/lib/libc/std/readline.c index c2237b6..ab13189 100644 --- a/src/user/lib/libc/std/readline.c +++ b/src/user/lib/libc/std/readline.c @@ -35,6 +35,10 @@ char* freadln(FILE f) { } } +char* readln() { + return freadln(term); +} + // ** READLINE diff --git a/src/user/lib/libc/std/stdio.c b/src/user/lib/libc/std/stdio.c index 23ec989..196c554 100644 --- a/src/user/lib/libc/std/stdio.c +++ b/src/user/lib/libc/std/stdio.c @@ -4,14 +4,16 @@ #include FILE term = 0; -void print(const char *s) { fprint(term, s); } +void print(const char *s) { + fprint(term, s); +} + void printf(const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(term, format, ap); va_end(ap); } -char* readln() { return freadln(term); } void fprint(FILE f, const char *s) { write(f, 0, strlen(s), s); -- cgit v1.2.3