diff options
Diffstat (limited to 'src/user/lib')
-rw-r--r-- | src/user/lib/dirent.c | 55 | ||||
-rw-r--r-- | src/user/lib/include/dirent.h | 20 | ||||
-rw-r--r-- | src/user/lib/stdio/file.c | 7 | ||||
-rw-r--r-- | src/user/lib/string/string.c | 2 |
4 files changed, 69 insertions, 15 deletions
diff --git a/src/user/lib/dirent.c b/src/user/lib/dirent.c new file mode 100644 index 0000000..c2d1b9c --- /dev/null +++ b/src/user/lib/dirent.c @@ -0,0 +1,55 @@ +#include <dirent.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +DIR *opendir(const char *name) { + FILE *fp = NULL; + DIR *dir = NULL; + fp = fopen(name, "r"); + if (!fp) { + goto err; + } + dir = calloc(1, sizeof *dir); + if (!dir) { + goto err; + } + dir->fp = fp; + return dir; +err: + if (fp) fclose(fp); + free(dir); + return NULL; +} + +int closedir(DIR *dir) { + fclose(dir->fp); + free(dir); + return 0; +} + +struct dirent *readdir(DIR *dir) { + int i = 0; + char *buf = dir->dent.d_name; + for (;;) { + int c = fgetc(dir->fp); + if (c == EOF) { + if (i == 0) return NULL; + else break; + } + if (c == '\0') { + break; + } + if (i == sizeof(dir->dent.d_name)-1) { + /* overflow */ + for (;;) { + c = fgetc(dir->fp); + if (c == EOF || c == '\0') break; + } + return errno = ENAMETOOLONG, NULL; + } + buf[i++] = c; + } + buf[i] = '\0'; + return &dir->dent; +} diff --git a/src/user/lib/include/dirent.h b/src/user/lib/include/dirent.h index 35ba1e9..7c419d7 100644 --- a/src/user/lib/include/dirent.h +++ b/src/user/lib/include/dirent.h @@ -1,20 +1,16 @@ #pragma once -#include <bits/panic.h> +#include <stdio.h> -typedef struct DIR DIR; struct dirent { ino_t d_ino; char d_name[256]; /* NAME_MAX + 1 */ }; -static inline DIR *opendir(const char *name) { - __libc_panic("unimplemented"); -} +typedef struct { + FILE *fp; + struct dirent dent; +} DIR; -static inline int closedir(DIR *dir) { - __libc_panic("unimplemented"); -} - -static inline struct dirent *readdir(DIR *dir) { - __libc_panic("unimplemented"); -} +DIR *opendir(const char *name); +int closedir(DIR *dir); +struct dirent *readdir(DIR *dir); diff --git a/src/user/lib/stdio/file.c b/src/user/lib/stdio/file.c index cbacfdd..9a6e555 100644 --- a/src/user/lib/stdio/file.c +++ b/src/user/lib/stdio/file.c @@ -155,8 +155,9 @@ size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) { errno = EBADF; return 0; } - if (size == 0) + if (size == 0) { return 0; + } while (pos < total) { long res = _sys_read(f->fd, buf + pos, total - pos, f->pos); @@ -207,6 +208,7 @@ int fputs(const char *s, FILE *f) { return fprintf(f, "%s\n", s); } +// TODO! c file buffering char *fgets(char *buf, int size, FILE *f) { char c = '\0'; long pos = 0; @@ -221,7 +223,8 @@ char *fgets(char *buf, int size, FILE *f) { int fgetc(FILE *f) { char c; - return fread(&c, 1, 1, f) ? c : EOF; + size_t ret = fread(&c, 1, 1, f); + return ret ? c : EOF; } int getc(FILE *f) { return fgetc(f); } diff --git a/src/user/lib/string/string.c b/src/user/lib/string/string.c index 68c4826..c65d7c5 100644 --- a/src/user/lib/string/string.c +++ b/src/user/lib/string/string.c @@ -5,7 +5,7 @@ #include <strings.h> char *strchr(const char *s, int c) { - for (; *s; s++) { + for (; *s || c == 0; s++) { if (*s == c) return (char *)s; } return NULL; |