summaryrefslogtreecommitdiff
path: root/src/user/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib')
-rw-r--r--src/user/lib/dirent.c55
-rw-r--r--src/user/lib/include/dirent.h20
-rw-r--r--src/user/lib/stdio/file.c7
-rw-r--r--src/user/lib/string/string.c2
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;