diff options
Diffstat (limited to 'src/lib/libc')
-rw-r--r-- | src/lib/libc/malloc.c | 13 | ||||
-rw-r--r-- | src/lib/libc/readline.c | 1 | ||||
-rw-r--r-- | src/lib/libc/setjmp.s | 75 | ||||
-rw-r--r-- | src/lib/libc/start.c | 3 | ||||
-rw-r--r-- | src/lib/libc/stdio.c | 191 | ||||
-rw-r--r-- | src/lib/libc/stdlib.c | 2 |
6 files changed, 176 insertions, 109 deletions
diff --git a/src/lib/libc/malloc.c b/src/lib/libc/malloc.c index 473404b..fd37f76 100644 --- a/src/lib/libc/malloc.c +++ b/src/lib/libc/malloc.c @@ -54,7 +54,10 @@ void malloc_setup() { void* malloc(size_t size) { if (size == 0) return 0; - return slab_alloc(mem_allocator, size); + //dbg_printf("malloc 0x%p -> ", size); + void* ret = slab_alloc(mem_allocator, size); + //dbg_printf("0x%p\n", ret); + return ret; } void* calloc(size_t nmemb, size_t sz) { @@ -64,10 +67,16 @@ void* calloc(size_t nmemb, size_t sz) { } void* realloc(void* ptr, size_t sz) { - return slab_realloc(mem_allocator, ptr, sz); + //dbg_printf("realloc 0x%p 0x%p -> ", ptr, sz); + void* ret = slab_realloc(mem_allocator, ptr, sz); + //dbg_printf("0x%p\n", ret); + return ret; } void free(void* ptr) { + if (ptr == 0) return; + + //dbg_printf("free 0x%p\n", ptr); slab_free(mem_allocator, ptr); } diff --git a/src/lib/libc/readline.c b/src/lib/libc/readline.c index 20c2007..c93bfe2 100644 --- a/src/lib/libc/readline.c +++ b/src/lib/libc/readline.c @@ -21,6 +21,7 @@ char *readline(const char* prompt) { // readline_history *h = &stdio_history; puts(prompt); + fflush(stdout); char* buf = malloc(READLINE_MAX_LEN); if (buf == NULL) return NULL; diff --git a/src/lib/libc/setjmp.s b/src/lib/libc/setjmp.s index 164cc5b..a9b5f48 100644 --- a/src/lib/libc/setjmp.s +++ b/src/lib/libc/setjmp.s @@ -1,24 +1,18 @@ [GLOBAL setjmp] setjmp: - ; Store general purpose registers - ; (in new stack frame) - mov [esp+4], eax - mov [esp+8], ebx - mov [esp+12], ecx - mov [esp+16], edx - mov [esp+20], edi - mov [esp+24], esi - mov [esp+28], ebp - mov [esp+32], esp - - ; Store flags - pushf - pop eax - mov [esp+36], eax + ; get return address + mov edx, [esp] + ; get address of jmpbuf structure + mov ecx, [esp+4] - ; Store return address - mov eax, [esp] - mov [esp+40], eax + ; Store general purpose registers + mov [ecx], ebx + mov [ecx+4], edx + mov [ecx+8], ebp + mov [ecx+12], esp + mov [ecx+16], esi + mov [ecx+20], edi + mov [ecx+24], eax ; return 0 xor eax, eax @@ -27,27 +21,26 @@ setjmp: [GLOBAL longjmp] longjmp: - ; on previous stack, resume return address - mov eax, [esp+32] - mov ebx, [esp+40] - mov [eax], ebx - - ; resume flags - mov eax, [esp+36] - push eax - popf - - ; load return value in eax - mov eax, [esp+44] - ; resume geneal purpose registers, except eax/esp - mov ebx, [esp+8] - mov ecx, [esp+12] - mov edx, [esp+16] - mov edi, [esp+20] - mov esi, [esp+24] - mov ebp, [esp+28] - - ; resume previous esp - mov esp, [esp+32] - ; return as if we were the setjmp call + ; get address of jmpbuf structure + mov ecx, [esp+4] + ; get retun value + mov eax, [esp+8] + + ; load general purpose registers + ; (edx contains the return address) + mov ebx, [ecx] + mov edx, [ecx+4] + mov ebp, [ecx+8] + mov esp, [ecx+12] + mov esi, [ecx+16] + mov edi, [ecx+20] + + ; make sure return value is nonzero + test eax, eax + jnz _doret + inc eax +_doret: + ; store back return address + mov [esp], edx ret + diff --git a/src/lib/libc/start.c b/src/lib/libc/start.c index 185d90f..49bf6a3 100644 --- a/src/lib/libc/start.c +++ b/src/lib/libc/start.c @@ -12,8 +12,9 @@ void __libc_start() { setup_libc_stdio(); // TODO : more setup ? yes, for args, for env... + char *argv[] = {"bin"}; - int ret = main(0, 0); + int ret = main(1, argv); sc_exit(ret); } diff --git a/src/lib/libc/stdio.c b/src/lib/libc/stdio.c index 8d4577e..c849683 100644 --- a/src/lib/libc/stdio.c +++ b/src/lib/libc/stdio.c @@ -10,15 +10,31 @@ FILE *stdin = 0; FILE *stdout = 0; FILE *stderr = 0; -void setup_libc_stdio() { - fd_t tty_io = STD_FD_TTY_STDIO; - // fd_t tty_in = STD_FD_STDIN; - // fd_t tty_out = STD_FD_STDOUT; - // fd_t tty_err = STD_FD_STDERR; +FILE libc_tty_stdio, libc_stdin, libc_stdout, libc_stderr; - // TODO - if (true) { - sc_fctl(tty_io, FC_SET_BLOCKING, 0); +void setup_libc_stdio() { + if (sc_stat_open(STD_FD_TTY_STDIO, &libc_tty_stdio.st)) { + libc_tty_stdio.fd = STD_FD_TTY_STDIO; + sc_fctl(libc_tty_stdio.fd, FC_SET_BLOCKING, 0); + // TODO: initialize libc_tty_stdio as a TTY + stdin = &libc_tty_stdio; + stdout = &libc_tty_stdio; + stderr = &libc_tty_stdio; + } + if (sc_stat_open(STD_FD_STDIN, &libc_stdin.st)) { + libc_stdin.fd = STD_FD_STDIN; + // TODO: initialize + stdin = &libc_stdin; + } + if (sc_stat_open(STD_FD_STDOUT, &libc_stdout.st)) { + libc_stdout.fd = STD_FD_STDOUT; + // TODO: initialize + stdout = &libc_stdout; + } + if (sc_stat_open(STD_FD_STDERR, &libc_stderr.st)) { + libc_stderr.fd = STD_FD_STDERR; + // TODO: initialize + stderr = &libc_stderr; } } @@ -37,13 +53,12 @@ int puts(const char* s) { int printf(const char* fmt, ...) { va_list ap; - char buffer[256]; va_start(ap, fmt); - vsnprintf(buffer, 256, fmt, ap); + int ret = vfprintf(stdout, fmt, ap); va_end(ap); - return puts(buffer); + return ret; } // ================== @@ -51,14 +66,59 @@ int printf(const char* fmt, ...) { // ================== -int fgetc(FILE *stream) { +FILE *fopen(const char *path, const char *mode) { // TODO return 0; } -char *fgets(char *s, int size, FILE *stream) { +FILE *freopen(const char *path, const char *mode, FILE *stream) { // TODO return 0; } +int fclose(FILE* f) { + // TODO + return 0; +} + + +// --------------- +// INPUT FUNCTIONS +// --------------- + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (stream == NULL || stream->fd == 0) return 0; + + // TODO buffering + // TODO position + return sc_read(stream->fd, 0, size * nmemb, ptr); +} + +int fgetc(FILE *stream) { + // TODO buffering && ungetc + char x; + if (fread(&x, 1, 1, stream)) { + return x; + } else { + return EOF; + } +} +char *fgets(char *s, int size, FILE *stream) { + int l = 0; + while (l < size - 1) { + int c = fgetc(stream); + if (c == EOF) { + break; + } else if (c == '\b') { + if (l > 0) l--; + // TODO if terminal write back space or something + } else { + s[l] = c; + l++; + if (c == '\n') break; + } + } + s[l] = 0; + return s; +} int getc(FILE *stream) { // TODO return 0; @@ -68,77 +128,90 @@ int ungetc(int c, FILE *stream) { return 0; } +// ---------------- +// OUTPUT FUNCTIONS +// ---------------- + +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (stream == NULL || stream->fd == 0) return 0; + + // TODO buffering + // TODO position + return sc_write(stream->fd, 0, size * nmemb, ptr); +} + int fputc(int c, FILE *stream) { - // TODO - return 0; + unsigned char x = c; + return fwrite(&x, 1, 1, stream); } int fputs(const char *s, FILE *stream) { - // TODO - return 0; + return fwrite(s, strlen(s), 1, stream); } int putc(int c, FILE *stream) { - // TODO - return 0; + return fputc(c, stream); } -FILE *fopen(const char *path, const char *mode) { - // TODO - return 0; +int fprintf(FILE *stream, const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + int ret = vfprintf(stream, fmt, ap); + va_end(ap); + + return ret; } -FILE *freopen(const char *path, const char *mode, FILE *stream) { - // TODO - return 0; +int vfprintf(FILE *stream, const char *format, va_list ap) { + char buf[1024]; + vsnprintf(buf, 1024, format, ap); + + return fputs(buf, stream); } -void clearerr(FILE *stream) { - // TODO +// buffering + +void setbuf(FILE *stream, char *buf) { + setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); } -int feof(FILE *stream) { +void setbuffer(FILE *stream, char *buf, size_t size) { // TODO - return 0; } -int ferror(FILE *stream) { +void setlinebuf(FILE *stream) { + setvbuf(stream, NULL, _IOLBF, 0); +} +int setvbuf(FILE *stream, char *buf, int mode, size_t size) { // TODO return 0; } -int fileno(FILE *stream) { + +int fflush(FILE* f) { // TODO return 0; } +// --------------------- +// COMPLICATED FUNCTIONS +// --------------------- -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { +void clearerr(FILE *stream) { // TODO - return 0; } -size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { +int feof(FILE *stream) { // TODO return 0; } - -int fflush(FILE* f) { +int ferror(FILE *stream) { // TODO return 0; } -int fclose(FILE* f) { +int fileno(FILE *stream) { // TODO return 0; } -void setbuf(FILE *stream, char *buf) { - // TODO -} -void setbuffer(FILE *stream, char *buf, size_t size) { - // TODO -} -void setlinebuf(FILE *stream) { - // TODO -} -int setvbuf(FILE *stream, char *buf, int mode, size_t size) { - // TODO - return 0; -} +// ------------------ +// POSITION FUNCTIONS +// ------------------ int fseek(FILE *stream, long offset, int whence) { @@ -161,6 +234,10 @@ int fsetpos(FILE *stream, const fpos_t *pos) { return 0; } +// --------------------- +// PATH & FILE FUNCTIONS +// --------------------- + FILE *tmpfile(void) { // TODO return 0; @@ -181,18 +258,4 @@ int remove(const char *pathname) { -int fprintf(FILE *stream, const char *format, ...) { - // TODO - return 0; -} -int dprintf(int fd, const char *format, ...) { - // TODO - return 0; -} -int sprintf(char *str, const char *format, ...) { - // TODO - return 0; -} - - /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/stdlib.c b/src/lib/libc/stdlib.c index 540d53c..7d08cd1 100644 --- a/src/lib/libc/stdlib.c +++ b/src/lib/libc/stdlib.c @@ -57,7 +57,7 @@ double strtod(const char *nptr, char **endptr) { for (int i = 0; i < exp; i++) val /= 10; } } - if (endptr != NULL) *endptr = (char*)(p-1); + if (endptr != NULL) *endptr = (char*)p; return val * sign; } |