summaryrefslogtreecommitdiff
path: root/src/user/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib/libc')
-rw-r--r--src/user/lib/libc/include/stdio.h13
-rw-r--r--src/user/lib/libc/include/string.h4
-rw-r--r--src/user/lib/libc/include/tce/syscall.h16
-rw-r--r--src/user/lib/libc/start.c13
-rw-r--r--src/user/lib/libc/std/stdio.c75
-rw-r--r--src/user/lib/libc/std/string.c54
-rw-r--r--src/user/lib/libc/tce/syscall.c16
7 files changed, 108 insertions, 83 deletions
diff --git a/src/user/lib/libc/include/stdio.h b/src/user/lib/libc/include/stdio.h
index d93ebf0..f19ce60 100644
--- a/src/user/lib/libc/include/stdio.h
+++ b/src/user/lib/libc/include/stdio.h
@@ -10,16 +10,13 @@ extern "C" { namespace libc {
extern FILE term;
-void print(char *s);
-void printf(char *s, ...);
+void print(const char *s);
+void printf(const char *s, ...);
char *readln();
-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, ...);
-
-void vfprintf(FILE f, char *s, va_list arg);
+void fprint(FILE f, const char *s);
+void fprintf(FILE f, const char *s, ...);
+void vfprintf(FILE f, const char *s, va_list arg);
#ifdef __cplusplus
} }
diff --git a/src/user/lib/libc/include/string.h b/src/user/lib/libc/include/string.h
index 54fdf7a..5b86868 100644
--- a/src/user/lib/libc/include/string.h
+++ b/src/user/lib/libc/include/string.h
@@ -2,6 +2,7 @@
#define DEF_LIB_STRING_H
#include <types.h>
+#include <stdarg.h>
#ifdef __cplusplus
extern "C" { namespace libc {
@@ -20,6 +21,9 @@ int strcmp(const char *s1, const char *s2);
char* format_int(char* buf, int number);
char* format_hex(char *buf, unsigned v);
+int printf_str_len(const char *fmt, va_list arg);
+int vsprintf(char *buf, const char *fmt, va_list arg);
+int sprintf(char *buf, const char *fmt, ...);
#ifdef __cplusplus
} }
diff --git a/src/user/lib/libc/include/tce/syscall.h b/src/user/lib/libc/include/tce/syscall.h
index 6ad37f1..6679f1a 100644
--- a/src/user/lib/libc/include/tce/syscall.h
+++ b/src/user/lib/libc/include/tce/syscall.h
@@ -15,7 +15,7 @@ void thread_exit();
void schedule();
void thread_sleep(int time);
void process_exit(int retval);
-void printk(char* str);
+void printk(const char* str);
void thread_new(void (*entry)(void*), void *data);
void irq_wait(int number);
int proc_priv();
@@ -23,18 +23,18 @@ int proc_priv();
void* sbrk(ptrdiff_t size);
void brk(void* ptr);
-int run(char* file, char** args, FILE zero_fd);
+int run(const char* file, const 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);
-int stat(char* filename, file_info *info);
-int stat_relative(FILE root, char* filename, file_info *info);
+FILE open(const char* filename, int mode);
+FILE open_relative(FILE root, const char* filename, int mode);
+int stat(const char* filename, file_info *info);
+int stat_relative(FILE root, const char* filename, file_info *info);
int statf(FILE file, file_info *info);
void close(FILE file);
int read(FILE file, size_t offset, size_t len, char *buffer);
-int write(FILE file, size_t offset, size_t len, char *buffer);
-int link(char* from, char* to, int mode);
+int write(FILE file, size_t offset, size_t len, const char *buffer);
+int link(const char* from, const char* to, int mode);
#ifdef __cplusplus
} }
diff --git a/src/user/lib/libc/start.c b/src/user/lib/libc/start.c
index 2521f97..f15f90d 100644
--- a/src/user/lib/libc/start.c
+++ b/src/user/lib/libc/start.c
@@ -2,7 +2,20 @@
extern int main(char **args);
+extern size_t start_ctors, end_ctors, start_dtors, end_dtors;
+
void start(char **args) {
+ size_t *call;
+
+ for (call = &start_ctors; call < &end_ctors; call++) {
+ ((void(*)(void))*call)();
+ }
+
int ret = main(args);
+
+ for (call = &start_dtors; call < &end_dtors; call++) {
+ ((void(*)(void))*call)();
+ }
+
process_exit(ret);
}
diff --git a/src/user/lib/libc/std/stdio.c b/src/user/lib/libc/std/stdio.c
index da2f094..23ec989 100644
--- a/src/user/lib/libc/std/stdio.c
+++ b/src/user/lib/libc/std/stdio.c
@@ -4,8 +4,8 @@
#include <readline.h>
FILE term = 0;
-void print(char *s) { fprint(term, s); }
-void printf(char *format, ...) {
+void print(const char *s) { fprint(term, s); }
+void printf(const char *format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(term, format, ap);
@@ -13,67 +13,24 @@ void printf(char *format, ...) {
}
char* readln() { return freadln(term); }
-void fprintf(FILE f, char* format, ...) {
+void fprint(FILE f, const char *s) {
+ write(f, 0, strlen(s), s);
+}
+
+void fprintf(FILE f, const char* format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(f, format, ap);
va_end(ap);
}
-// 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 vfprintf(FILE f, char *format, va_list ap) {
- char bb[256];
- int bufl = 256;
-
- char *buf = bb;
- char *end = buf;
-
- while (*format) {
- if (*format == '%') {
- // ASSUMPTION : (TODO) WE HAVE ENOUGH SPACE - NOT THE CASE!!!
- format++;
- if (*format == 'd' || *format == 'i') {
- end = format_int(end, va_arg(ap, int));
- } else if (*format == 'p') {
- end = format_hex(end, va_arg(ap, uint32_t));
- } else if (*format == 's') {
- char *s = va_arg(ap, char*);
- strcpy(end, s);
- end += strlen(s);
- }
- format++;
- } else {
- *(end++) = *(format++);
- }
- 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;
- }
- }
- *end = 0;
- fprint(f, buf);
- if (buf != bb) free(buf);
+void vfprintf(FILE f, const char *fmt, va_list ap) {
+ va_list ap2;
+ va_copy(ap2, ap);
+ int l = printf_str_len(fmt, ap2);
+ va_end(ap2);
+ char* buf = (char*) malloc(l+1);
+ l = vsprintf(buf, fmt, ap);
+ if (l > 0) write(f, 0, l, buf);
+ free(buf);
}
diff --git a/src/user/lib/libc/std/string.c b/src/user/lib/libc/std/string.c
index d8e4a48..619b8c6 100644
--- a/src/user/lib/libc/std/string.c
+++ b/src/user/lib/libc/std/string.c
@@ -119,3 +119,57 @@ char* format_hex(char *buf, unsigned v) {
}
return buf;
}
+
+int printf_str_len(const char *format, va_list ap) {
+ int l = 0;
+ while (*format) {
+ if (*format == '%') {
+ format++;
+ if (*format == 'd' || *format == 'i') {
+ l += 15;
+ va_arg(ap, int);
+ } else if (*format == 'p') {
+ l += 11;
+ va_arg(ap, void*);
+ } else if (*format == 's') {
+ l += strlen(va_arg(ap, const char*));
+ }
+ } else {
+ l++;
+ }
+ format++;
+ }
+ return l;
+}
+
+int sprintf(char *buf, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = vsprintf(buf, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+int vsprintf(char *buf, const char *format, va_list ap) {
+ char *end = buf;
+
+ while (*format) {
+ if (*format == '%') {
+ format++;
+ if (*format == 'd' || *format == 'i') {
+ end = format_int(end, va_arg(ap, int));
+ } else if (*format == 'p') {
+ end = format_hex(end, va_arg(ap, uint32_t));
+ } else if (*format == 's') {
+ const char *s = va_arg(ap, const char*);
+ strcpy(end, s);
+ end += strlen(s);
+ }
+ format++;
+ } else {
+ *(end++) = *(format++);
+ }
+ }
+ *end = 0;
+ return end - buf;
+}
diff --git a/src/user/lib/libc/tce/syscall.c b/src/user/lib/libc/tce/syscall.c
index 80e0e0e..acdcc51 100644
--- a/src/user/lib/libc/tce/syscall.c
+++ b/src/user/lib/libc/tce/syscall.c
@@ -25,7 +25,7 @@ void process_exit(int retval) {
call(SC_PROCESS_EXIT, retval, 0, 0, 0, 0);
}
-void printk(char* str) {
+void printk(const char* str) {
call(SC_PRINTK, (unsigned)str, 0, 0, 0, 0);
}
@@ -75,7 +75,7 @@ void brk(void* ptr) {
// ********** proc
-int run(char* filename, char** args, FILE zero_fd) {
+int run(const char* filename, const char** args, FILE zero_fd) {
return call(SC_RUN, (unsigned)filename, (unsigned)args, (unsigned)zero_fd, 0, 0);
}
@@ -85,19 +85,19 @@ int waitpid(int p, int block) {
// ********** file
-FILE open(char* filename, int mode) {
+FILE open(const char* filename, int mode) {
return call(SC_OPEN, (unsigned)filename, mode, 0, 0, 0);
}
-FILE open_relative(FILE root, char* filename, int mode) {
+FILE open_relative(FILE root, const char* filename, int mode) {
return call(SC_OPEN_RELATIVE, root, (unsigned) filename, mode, 0, 0);
}
-int stat(char* filename, file_info *info) {
+int stat(const char* filename, file_info *info) {
return call(SC_STAT, (unsigned) filename, (unsigned) info, 0, 0, 0);
}
-int stat_relative(FILE root, char* filename, file_info *info) {
+int stat_relative(FILE root, const char* filename, file_info *info) {
return call(SC_STAT_RELATIVE, root, (unsigned) filename, (unsigned) info, 0, 0);
}
@@ -113,10 +113,10 @@ int read(FILE file, size_t offset, size_t len, char *buffer) {
return call(SC_READ, file, offset, len, (unsigned) buffer, 0);
}
-int write(FILE file, size_t offset, size_t len, char* buffer) {
+int write(FILE file, size_t offset, size_t len, const char* buffer) {
return call(SC_WRITE, file, offset, len, (unsigned) buffer, 0);
}
-int link(char* from, char* to, int mode) {
+int link(const char* from, const char* to, int mode) {
return call(SC_LINK, (unsigned) from, (unsigned)to, mode, 0, 0);
}