diff options
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/app/find/find.c | 60 | ||||
-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 |
5 files changed, 93 insertions, 51 deletions
diff --git a/src/user/app/find/find.c b/src/user/app/find/find.c index 529b54e..d473b82 100644 --- a/src/user/app/find/find.c +++ b/src/user/app/find/find.c @@ -1,55 +1,43 @@ #include <camellia/path.h> +#include <dirent.h> +#include <err.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#define eprintf(fmt, ...) fprintf(stderr, "find: "fmt"\n" __VA_OPT__(,) __VA_ARGS__) - void recurse(char *path) { - FILE *f = fopen(path, "r"); - const int buf_len = 4096; - char *buf; - - if (!f) { - eprintf("couldn't open %s", path); + DIR *d = opendir(path); + if (!d) { + warn("couldn't open %s", path); return; } - - buf = malloc(buf_len); for (;;) { - int len = fread(buf, 1, buf_len, f); - int pos = 0; - if (len <= 0) break; - while (pos < len) { - if (buf[pos] == '\0') { - eprintf("%s has an empty entry, bailing", path); - break; - } - const char *end = memchr(buf + pos, 0, len - pos); - if (!end) { - eprintf("buf overflowed, unimplemented"); // TODO - break; + struct dirent *dent; + errno = 0; + dent = readdir(d); + if (!dent) { + if (errno) { + warn("when reading %s", path); } - printf("%s%s\n", path, buf + pos); - - size_t entrylen = end - (buf + pos) + 1; - if (end[-1] == '/') { - // append onto end of the current path - // TODO no overflow check - char *pend = path + strlen(path); - memcpy(pend, buf + pos, entrylen); - recurse(path); - *pend = '\0'; - } - pos += entrylen; + break; + } + printf("%s%s\n", path, dent->d_name); + /* if the string ends with '/' */ + if (strchr(dent->d_name, '\0')[-1] == '/') { + // TODO no overflow check + char *pend = strchr(path, '\0'); + strcpy(pend, dent->d_name); + recurse(path); + *pend = '\0'; } } - fclose(f); - free(buf); + closedir(d); } void find(const char *path) { // TODO bound checking + // TODO or just implement asprintf() char *buf = malloc(PATH_MAX); memcpy(buf, path, strlen(path)+1); recurse(buf); 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; |