From ed48a8b1b4f9dfe3d998865ad743c069fbc75f56 Mon Sep 17 00:00:00 2001 From: Ali Mashtizadeh Date: Tue, 14 Oct 2014 18:00:14 -0700 Subject: [PATCH] Partial implementation of some of libc's FILE operations --- include/stdio.h | 32 +++++++++ include/syscall.h | 3 +- include/unistd.h | 4 ++ lib/libc/SConscript | 1 + lib/libc/file.c | 160 ++++++++++++++++++++++++++++++++++++++++++++ lib/libc/syscall.c | 8 ++- sys/include/types.h | 3 + 7 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 lib/libc/file.c diff --git a/include/stdio.h b/include/stdio.h index 89deb0f..00621ea 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -2,5 +2,37 @@ #ifndef __STDIO_H__ #define __STDIO_H__ +#include + +typedef struct FILE { + int in_use; + uint64_t fd; /* Kernel File Descriptor */ + fpos_t offset; +} FILE; + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define EOF (-1) + +extern FILE *stdin; +extern FILE *stdout; +extern FILE *stderr; + +#define FOPEN_MAX 16 + +FILE *fopen(const char *path, const char *mode); +int fclose(FILE *fh); +int feof(FILE *fh); +int fflush(FILE *fh); +size_t fread(void *buf, size_t size, size_t nmemb, FILE *fh); +size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *fh); + +int fputc(int ch, FILE *fh); +int fputs(const char *str, FILE *fh); +int fgetc(FILE *fh); +char *fgets(char *str, int size, FILE *fh); + #endif /* __STDIO_H__ */ diff --git a/include/syscall.h b/include/syscall.h index 973d9ee..afbbd36 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -13,9 +13,10 @@ int SystemMemProtect(void *addr, uint64_t len, int flags); // IO int SystemRead(uint64_t fd, void *addr, uint64_t off, uint64_t length); -int SystemWrite(uint64_t fd, void *addr, uint64_t off, uint64_t length); +int SystemWrite(uint64_t fd, const void *addr, uint64_t off, uint64_t length); int SystemFlush(uint64_t fd); uint64_t SystemOpen(const char *path, uint64_t flags); +int SystemClose(uint64_t fd); #endif /* __SYSCALL_H__ */ diff --git a/include/unistd.h b/include/unistd.h index d608ad4..37c2a54 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -2,6 +2,10 @@ #ifndef __UNISTD_H__ #define __UNISTD_H__ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + int syscall(int number, ...); #endif /* __UNISTD_H__ */ diff --git a/lib/libc/SConscript b/lib/libc/SConscript index f934b53..809cd99 100644 --- a/lib/libc/SConscript +++ b/lib/libc/SConscript @@ -9,6 +9,7 @@ src = [ ] src_common = [ "assert.c", "exit.c", + "file.c", "syscall.c", "posix/mman.c", ] diff --git a/lib/libc/file.c b/lib/libc/file.c new file mode 100644 index 0000000..a86cfd7 --- /dev/null +++ b/lib/libc/file.c @@ -0,0 +1,160 @@ + +#include +#include +#include + +#include + +#include + +static FILE __stdin = { 1, STDIN_FILENO, 0 }; +static FILE __stdout = { 1, STDOUT_FILENO, 0 }; +static FILE __stderr = { 1, STDERR_FILENO, 0 }; + +FILE *stdin = &__stdin; +FILE *stdout = &__stdout; +FILE *stderr = &__stderr; + +static FILE fds[FOPEN_MAX] = { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, +}; + +FILE * +_alloc_file() +{ + for (int i = 0; i < FOPEN_MAX; i++) { + if (fds[i].in_use == 0) { + fds[i].in_use = 1; + return &fds[i]; + } + } + + // XXX: malloc +} + +void +_free_file(FILE *fh) +{ + fh->fd = 0; + fh->offset = 0; + fh->in_use = 0; + + // XXX: free +} + +FILE * +fopen(const char *path, const char *mode) +{ + uint64_t fd; + FILE *fh; + // XXX: handle mode + + fd = SystemOpen(path, 0); + if (fd == 0) + return NULL; + + fh = _alloc_file(); + fh->fd = fd; + fh->offset = 0; + + // XXX: handle append + + return fh; +} + +int +fclose(FILE *fh) +{ + int status = SystemClose(fh->fd); + + _free_file(fh); + + return status; +} + +int +feof(FILE *fh) +{ +} + +int +fflush(FILE *fh) +{ +} + +size_t +fread(void *buf, size_t size, size_t nmemb, FILE *fh) +{ + return SystemRead(fh->fd, buf, 0, size * nmemb); + // set errno +} + +size_t +fwrite(const void *buf, size_t size, size_t nmemb, FILE *fh) +{ + return SystemWrite(fh->fd, buf, 0, size * nmemb); + // set errno +} + +int +fputc(int ch, FILE *fh) +{ + if (fwrite(&ch, 1, 1, fh) == 1) + return ch; + return EOF; +} + +int +fputs(const char *str, FILE *fh) +{ + int status = fwrite(str, strlen(str), 1, fh); + if (status > 0) + return status; + // XXX: error handling + return EOF; +} + +int +fgetc(FILE *fh) +{ + char ch; + if (fread(&ch, 1, 1, fh) == 1) + return ch; + return EOF; +} + +char * +fgets(char *str, int size, FILE *fh) +{ + int i; + + for (i = 0; i < (size - 1); i++) { + int ch = fgetc(fh); + if (ch == EOF) + return NULL; + str[i] = (char)ch; + if (ch == '\n') { + str[i + 1] = '\0'; + return str; + } + } + + str[size - 1] = '\0'; + return str; +} + diff --git a/lib/libc/syscall.c b/lib/libc/syscall.c index af4fa24..a39c097 100644 --- a/lib/libc/syscall.c +++ b/lib/libc/syscall.c @@ -50,7 +50,7 @@ SystemRead(uint64_t fd, void *addr, uint64_t off, uint64_t length) } int -SystemWrite(uint64_t fd, void *addr, uint64_t off, uint64_t length) +SystemWrite(uint64_t fd, const void *addr, uint64_t off, uint64_t length) { return syscall(SYSCALL_WRITE, fd, addr, off, length); } @@ -67,3 +67,9 @@ SystemOpen(const char *path, uint64_t flags) return syscall(SYSCALL_OPEN, path, flags); } +int +SystemClose(uint64_t fd) +{ + return syscall(SYSCALL_CLOSE, fd); +} + diff --git a/sys/include/types.h b/sys/include/types.h index d7b226a..61b1703 100644 --- a/sys/include/types.h +++ b/sys/include/types.h @@ -18,6 +18,9 @@ typedef uint64_t size_t; typedef int64_t ssize_t; typedef int64_t off_t; +typedef int64_t fpos_t; + +#define NULL ((void *)0) #endif /* __SYS_TYPES_H__ */