summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2012-05-19 16:38:56 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2012-05-19 16:38:56 +0200
commitd502fce7d4db492690e39c72fc029aa05a65057d (patch)
treea5797a97212fff8142dc7f61792facca07c904eb
parent8e07c1db6ba4bedd0f8fe537a6fb0ca80e5d25f4 (diff)
downloadTCE-d502fce7d4db492690e39c72fc029aa05a65057d.tar.gz
TCE-d502fce7d4db492690e39c72fc029aa05a65057d.zip
More improvements in FWIK - more strings, Dir class, ...
-rw-r--r--src/include/tce/syscalls.h1
-rw-r--r--src/kernel/task/task.cpp3
-rw-r--r--src/user/app/test/main.c4
-rw-r--r--src/user/app/yosh/main.cpp94
-rw-r--r--src/user/lib/fwik/Makefile2
-rw-r--r--src/user/lib/fwik/include/IO/Dir.h24
-rw-r--r--src/user/lib/fwik/include/IO/Node.h5
-rw-r--r--src/user/lib/fwik/io/Dir.cpp37
-rw-r--r--src/user/lib/fwik/io/Node.cpp24
-rw-r--r--src/user/lib/fwik/io/Term.cpp12
-rw-r--r--src/user/lib/libc/include/readline.h1
-rw-r--r--src/user/lib/libc/include/stdio.h1
-rw-r--r--src/user/lib/libc/std/readline.c4
-rw-r--r--src/user/lib/libc/std/stdio.c6
14 files changed, 149 insertions, 69 deletions
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 <stdio.h>
#include <readline.h>
#include <IO/IOStream.h>
+#include <IO/Dir.h>
-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 <String.h>
+
+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 <String.h>
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 <IO/Dir.h>
+
+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 <readline.h>
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);