summaryrefslogtreecommitdiff
path: root/src/user/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib')
-rw-r--r--src/user/lib/Makefile2
-rw-r--r--src/user/lib/include/readline.h16
-rw-r--r--src/user/lib/include/stdio.h4
-rw-r--r--src/user/lib/include/tce/syscall.h4
-rw-r--r--src/user/lib/std/readline.c139
-rw-r--r--src/user/lib/std/stdio.c124
-rw-r--r--src/user/lib/tce/syscall.c8
7 files changed, 222 insertions, 75 deletions
diff --git a/src/user/lib/Makefile b/src/user/lib/Makefile
index 9111ff5..c2630c4 100644
--- a/src/user/lib/Makefile
+++ b/src/user/lib/Makefile
@@ -1,6 +1,6 @@
Out = _user.o
Obj = tce/syscall.o std/_dlmalloc.o \
- std/stdio.o std/stdlib.o std/string.o std/sched.o \
+ std/stdio.o std/stdlib.o std/string.o std/sched.o std/readline.o \
start.o
include $(SrcPath)/common.make
diff --git a/src/user/lib/include/readline.h b/src/user/lib/include/readline.h
new file mode 100644
index 0000000..53193d7
--- /dev/null
+++ b/src/user/lib/include/readline.h
@@ -0,0 +1,16 @@
+#ifndef DEF_READLINE_H
+#define DEF_READLINE_H
+
+#include <stdio.h>
+
+char* freadln(FILE f); // minimal line-reading function. user must free the returned value.
+
+typedef struct _rdln_hist {
+ int max;
+ int n;
+ char **str;
+} readline_history;
+char* readline(FILE f, readline_history *h);
+
+#endif
+
diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h
index 6c3a974..099746e 100644
--- a/src/user/lib/include/stdio.h
+++ b/src/user/lib/include/stdio.h
@@ -2,6 +2,7 @@
#define DEF_STDIO_H
#include <stdarg.h>
+#include <tce/syscall.h>
extern FILE term;
@@ -14,8 +15,7 @@ void fprint_int(FILE f, int number);
void fprint_hex(FILE f, unsigned number);
void fprintf(FILE f, char *s, ...);
-void vsfprintf(FILE f, char *s, va_list arg);
+void vfprintf(FILE f, char *s, va_list arg);
-char* freadln(FILE f);
#endif
diff --git a/src/user/lib/include/tce/syscall.h b/src/user/lib/include/tce/syscall.h
index 1811422..c182f40 100644
--- a/src/user/lib/include/tce/syscall.h
+++ b/src/user/lib/include/tce/syscall.h
@@ -19,8 +19,8 @@ int proc_priv();
void* sbrk(size_t size);
void brk(void* ptr);
-int run(char* file, char** args);
-int waitpid(int pid);
+int run(char* file, char** args, FILE zero_fd);
+int waitpid(int pid, int block);
FILE open(char* filename, int mode);
FILE open_relative(FILE root, char* filename, int mode);
diff --git a/src/user/lib/std/readline.c b/src/user/lib/std/readline.c
new file mode 100644
index 0000000..a3beefa
--- /dev/null
+++ b/src/user/lib/std/readline.c
@@ -0,0 +1,139 @@
+#include <readline.h>
+#include <stdlib.h>
+
+char* freadln(FILE f) {
+ fprint(f, "\x1b[e"); // enable keyboard echo
+ 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;
+ } else if (b[i] == 27) { // ignore escape sequences
+ b[i] = 0;
+ l = i;
+ }
+ }
+
+ int d = b - p + l;
+
+ char* newp = (char*)malloc(d + 256);
+ memcpy(newp, p, d);
+ free(p);
+ p = newp;
+ b = p + d;
+ }
+}
+
+
+// ** READLINE
+
+char *readline(FILE f, readline_history *h) {
+ int i;
+ fprint(f, "\x1b[h"); // disable keyboard echo
+
+ if (h->str == 0) {
+ h->str = (char**)malloc(h->max * sizeof(char*));
+ for (i = 0; i < h->max; i++) h->str[i] = 0;
+ h->n = 0;
+ }
+
+ int lid;
+ if (h->n < h->max) {
+ lid = h->n++;
+ } else {
+ free(h->str[0]);
+ int i;
+ for (i = 0; i < h->max - 1; i++) {
+ h->str[i] = h->str[i+1];
+ }
+ lid = h->max - 1;
+ h->str[lid] = 0;
+ }
+
+ if (h->str[lid] == 0) h->str[lid] = (char*)malloc(256);
+
+ char *str = h->str[lid];
+ str[0] = 0;
+ char *cur = str; // position in string
+ int len = 0; // string length
+
+ while (1) {
+ int finished = 0;
+
+ int te = cur - str;
+
+ char buf[16];
+ int l = read(f, 0, 16, buf);
+ if (l < 0) return 0;
+
+ if (buf[0] == 27) {
+ if (buf[1] == '[') {
+ if (buf[2] == 'A') { // up
+ if (lid > 0) {
+ lid--;
+ str = h->str[lid];
+ len = strlen(str);
+ cur = str + len;
+ }
+ } else if (buf[2] == 'B') { // down
+ if (lid < h->n - 1) {
+ lid++;
+ str = h->str[lid];
+ len = strlen(str);
+ cur = str + len;
+ }
+ } else if (buf[2] == 'C') { // forward (right)
+ if (cur < str + len) cur++;
+ } else if (buf[2] == 'D') { // back (left)
+ if (cur > str) cur--;
+ }
+ } else {
+ // ALT sequence - ignore
+ }
+ } else if (buf[0] == '\n') {
+ finished = 1;
+ cur = str + len;
+ } else if (buf[0] == '\b') {
+ if (cur > str) {
+ cur--;
+ len--;
+ char* c;
+ for (c = cur; *c != 0; c++) c[0] = c[1];
+ }
+ } else if (buf[0] == '\t') {
+ // ignore tabs -- todo: tab completion???? haha
+ } else if (buf[0] >= ' ') {
+ if (l < 255) {
+ char* c;
+ for (c = cur + len; c >= cur; c--) c[1] = c[0];
+ cur[0] = buf[0];
+ cur++;
+ len++;
+ }
+ }
+
+ // ASSUMPTION : everything will fit on one line...
+ if (te > 0) fprintf(f, "\x1b[%iD", te);
+ fprintf(f, "\x1b[K%s", str);
+ te = len - (cur - str);
+ if (te > 0) fprintf(f, "\x1b[%iD", te);
+
+
+ if (finished) {
+ fprintf(f, "\n");
+ if (h->str[h->n-1][0] == 0) h->n--;
+ return str;
+ }
+ }
+}
diff --git a/src/user/lib/std/stdio.c b/src/user/lib/std/stdio.c
index 1628a78..b1778d6 100644
--- a/src/user/lib/std/stdio.c
+++ b/src/user/lib/std/stdio.c
@@ -7,7 +7,7 @@ void print(char *s) { fprint(term, s); }
void printf(char *format, ...) {
va_list ap;
va_start(ap, format);
- vsfprintf(term, format, ap);
+ vfprintf(term, format, ap);
va_end(ap);
}
char* readln() { return freadln(term); }
@@ -15,25 +15,22 @@ char* readln() { return freadln(term); }
void fprintf(FILE f, char* format, ...) {
va_list ap;
va_start(ap, format);
- vsfprintf(f, format, ap);
+ vfprintf(f, format, ap);
va_end(ap);
}
+// INTERNAL, FOR FORMATTING
-void fprint(FILE f, char *s) {
- write(f, 0, strlen(s), s);
-}
-
-void fprint_int(FILE f, int number) {
+static char* format_int(char* buf, int number) {
if (number == 0) {
- fprint(f, "0");
- return;
+ *(buf++) = '0';
+ return buf;
}
- int negative = 0;
if (number < 0) {
- negative = 1;
+ *(buf++) = '-';
number = 0 - number;
}
+
int order = 0, temp = number, i;
char numbers[] = "0123456789";
while (temp > 0) {
@@ -41,86 +38,81 @@ void fprint_int(FILE f, int number) {
temp /= 10;
}
- char s[32], *r;
- if (negative) {
- s[0] = '-';
- r = s + 1;
- } else {
- r = s;
- }
-
for (i = order; i > 0; i--) {
- r[i - 1] = numbers[number % 10];
+ buf[i - 1] = numbers[number % 10];
number /= 10;
}
- r[order] = 0;
- fprint(f, s);
+ return buf + order;
}
-void fprint_hex(FILE f, unsigned v) {
- char s[11] = {'0', 'x', 0};
+static char* format_hex(char *buf, unsigned v) {
+ *(buf++) = '0';
+ *(buf++) = 'x';
int i;
-
char hexdigits[] = "0123456789ABCDEF";
-
for (i = 0; i < 8; i++) {
- s[i + 2] = (hexdigits[v >> 28]);
+ *(buf++) = hexdigits[v >> 28];
v = v << 4;
}
- s[11] = 0;
+ return buf;
+}
+
+
+// FUNCTIONS
+
+void fprint(FILE f, char *s) {
+ write(f, 0, strlen(s), s);
+}
+
+void fprint_int(FILE f, int number) {
+ char s[32];
+ char *v = format_int(s, number);
+ *v = 0;
+ fprint(f, s);
+}
+
+void fprint_hex(FILE f, unsigned v) {
+ char s[11];
+ char *e = format_hex(s, v);
+ *e = 0;
fprint(f, s);
}
-void vsfprintf(FILE f, char *format, va_list ap) {
- char* start = format;
+void vfprintf(FILE f, char *format, va_list ap) {
+ char bb[256];
+ int bufl = 256;
+
+ char *buf = bb;
+ char *end = buf;
while (*format) {
if (*format == '%') {
- if (start != format) write(f, 0, format - start, start);
+ // ASSUMPTION : (TODO) WE HAVE ENOUGH SPACE - NOT THE CASE!!!
format++;
if (*format == 'd' || *format == 'i') {
- fprint_int(f, va_arg(ap, int));
+ end = format_int(end, va_arg(ap, int));
} else if (*format == 'p') {
- fprint_hex(f, va_arg(ap, uint32_t));
+ end = format_hex(end, va_arg(ap, uint32_t));
} else if (*format == 's') {
- fprint(f, va_arg(ap, char*));
+ char *s = va_arg(ap, char*);
+ strcpy(end, s);
+ end += strlen(s);
}
format++;
- start = format;
} else {
- format++;
+ *(end++) = *(format++);
}
- }
- if (start != format) write(f, 0, format - start, start);
-}
-
-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;
+ if (end - buf > bufl - 2) {
+ bufl *= 2;
+ char *nbuf = (char*)malloc(bufl);
+ memcpy(nbuf, buf, end - buf);
+ end = nbuf + (end - buf);
+ if (buf != bb) free(buf);
+ buf = nbuf;
}
-
- 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;
}
+ *end = 0;
+ fprint(f, buf);
+ if (buf != bb) free(buf);
}
diff --git a/src/user/lib/tce/syscall.c b/src/user/lib/tce/syscall.c
index bc8bfd8..4304840 100644
--- a/src/user/lib/tce/syscall.c
+++ b/src/user/lib/tce/syscall.c
@@ -75,12 +75,12 @@ void brk(void* ptr) {
// ********** proc
-int run(char* filename, char** args) {
- return call(SC_RUN, (unsigned)filename, (unsigned)args, 0, 0, 0);
+int run(char* filename, char** args, FILE zero_fd) {
+ return call(SC_RUN, (unsigned)filename, (unsigned)args, (unsigned)zero_fd, 0, 0);
}
-int waitpid(int p) {
- return call(SC_WAITPID, p, 0, 0, 0, 0);
+int waitpid(int p, int block) {
+ return call(SC_WAITPID, p, block, 0, 0, 0);
}
// ********** file