9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 5dce7e124ce0295bdbad9200116ca0f05936ace7
parent a6b5d915eca0a0031e0aea86553c0dc11282ded3
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Tue, 12 Feb 2019 13:01:30 +0000

[drivers] Add diretory read support

Change-Id: I389769409ef6fceb14ac7273fddac974be6c611c

Diffstat:
Mdrivers/dev.c | 7+++----
Minclude/libk.h | 16++++++++++++++++
Minclude/rcode/9p.h | 8+++++++-
Mscripts/rules.mk | 2+-
Msrc/lib9p/Makefile | 6+++++-
Dsrc/lib9p/conv.h | 8--------
Asrc/lib9p/convfr9p.h | 8++++++++
Asrc/lib9p/convto9p.h | 8++++++++
Dsrc/lib9p/dirto9p.c | 36------------------------------------
Asrc/lib9p/dirtop9.c | 36++++++++++++++++++++++++++++++++++++
Asrc/lib9p/frombytes.c | 24++++++++++++++++++++++++
Asrc/lib9p/fromstring.c | 34++++++++++++++++++++++++++++++++++
Asrc/lib9p/p9todir.c | 40++++++++++++++++++++++++++++++++++++++++
Msrc/lib9p/tobytes.c | 2+-
Msrc/lib9p/tostring.c | 2+-
Msrc/libk/Makefile | 3+++
Asrc/libk/kclosedir.c | 8++++++++
Asrc/libk/kopendir.c | 20++++++++++++++++++++
Asrc/libk/kreaddir.c | 21+++++++++++++++++++++
Msrc/romfw/dlang.c | 25+++++++++++++++++++++++++
Mtarget/native/rom.c | 8+++-----
21 files changed, 264 insertions(+), 58 deletions(-)

diff --git a/drivers/dev.c b/drivers/dev.c @@ -241,6 +241,7 @@ devattach(const char *spec, int id) return NULL; c->qid = CHDIR; c->type = devtype(id); + return c; } @@ -285,10 +286,10 @@ devdirread(Chan *c, case -1: return cnt; case 0: - c->offset += DIRLEN; break; case 1: - n = dirto9p(&dir, buf + cnt, -1); + c->offset += DIRLEN; + n = dirto9p(&dir, buf + cnt, nbytes); nbytes -= n; cnt += n; } @@ -354,7 +355,6 @@ read(int fd, void *buf, int n) return -1; } n = devtab[c->type]->read(c, buf, n); - c->offset += n; return n; } @@ -372,7 +372,6 @@ write(int fd, void *buf, int n) } n = devtab[c->type]->write(c, buf, n); - c->offset += n; return n; } diff --git a/include/libk.h b/include/libk.h @@ -1,8 +1,20 @@ #include <stdarg.h> #include <stddef.h> +#include <rcode/9p.h> + #include "features.h" +struct dirent { + char d_name[NAMELEN]; +}; + +typedef struct { + int fd; + unsigned char buf[DIRLEN]; + struct dirent ent; +} DIR; + extern int kprint(const char *fmt, ...) KPRINTFMT; extern int ksnprint(char *str, size_t len, const char *fmt, ...) KSNPRINTFMT; extern char *kgets(char *s, int n); @@ -12,3 +24,7 @@ extern int kputs(const char *s); extern int kvprint(const char *fmt, va_list va); extern void kerror(const char *s); extern int putenv(char *name); + +extern DIR *kopendir(DIR *dir, const char *name); +extern struct dirent *kreaddir(DIR *dir); +extern int kclosedir(DIR *dir); diff --git a/include/rcode/9p.h b/include/rcode/9p.h @@ -1,3 +1,6 @@ +#ifndef LIBK_H_ +#define LIBK_H_ + #define NAMELEN 8 #define STATLEN 41 #define ROOTLEN (2 + 4) @@ -16,4 +19,7 @@ struct dir { Qid qid; }; -extern int dirto9p(Dir *dp, unsigned char *buf, int n); +extern int dirtop9(Dir *dp, unsigned char *buf, int n); +extern int p9todir(Dir *dp, unsigned char *buf, int n); + +#endif diff --git a/scripts/rules.mk b/scripts/rules.mk @@ -12,7 +12,7 @@ SRCDIR = $(PROJECTDIR)/src SCRIPTDIR = $(PROJECTDIR)/scripts CONFDIR = $(PROJECTDIR)/config INCLUDES = -I$(INCDIR) -I$(INCDIR)/bits/$(ARCH)/ -I$(INCDIR)/bits/$(SYS) -LIBS = -l9p -lhdl -lrmu -lk -lc +LIBS = -lhdl -lrmu -lk -l9p -lc DRIVERS = $(PROJECTDIR)/drivers/builtin.o ENVIRON = $(SCRIPTDIR)/env.sh diff --git a/src/lib9p/Makefile b/src/lib9p/Makefile @@ -4,7 +4,11 @@ include $(PROJECTDIR)/scripts/rules.mk OBJS = tobytes.o \ tostring.o \ - dirto9p.o \ + dirtop9.o \ + frombytes.o \ + fromstring.o \ + p9todir.o \ + TARGET = $(LIBDIR)/lib9p.a diff --git a/src/lib9p/conv.h b/src/lib9p/conv.h @@ -1,8 +0,0 @@ -#define CHAR(x,p) (p = tobytes(p, x, 1)) -#define SHORT(x,p) (p = tobytes(p, x, 2)) -#define LONG(x,p) (p = tobytes(p, x, 4)) -#define LLONG(x,p) (p = tobytes(p, x, 8)) -#define STRING(s,p) (p = tostring(p, s)) - -unsigned char *tobytes(unsigned char *p, unsigned long long v, int nbytes); -unsigned char *tostring(unsigned char *p, char *s); diff --git a/src/lib9p/convfr9p.h b/src/lib9p/convfr9p.h @@ -0,0 +1,8 @@ +#define CHAR(v, b, n, m) (v = frombytes(b, &n, m, 1)) +#define SHORT(v, b, n, m) (v = frombytes(b, &n, m, 2)) +#define LONG(v, b, n, m) (v = frombytes(b, &n, m, 4)) +#define LLONG(v, b, n, m) (v = frombytes(b, &n, m, 8)) +#define STRING(str, s, b, n, m) (fromstring(b, &n, m, str, s)) + +extern long long frombytes(unsigned char *b, int *n, int max, int nbytes); +extern char *fromstring(unsigned char *b, int *n, int max, char *str, int s); diff --git a/src/lib9p/convto9p.h b/src/lib9p/convto9p.h @@ -0,0 +1,8 @@ +#define CHAR(x,p) (p = tobytes(p, x, 1)) +#define SHORT(x,p) (p = tobytes(p, x, 2)) +#define LONG(x,p) (p = tobytes(p, x, 4)) +#define LLONG(x,p) (p = tobytes(p, x, 8)) +#define STRING(s,p) (p = tostring(p, s)) + +unsigned char *tobytes(unsigned char *p, unsigned long long v, int nbytes); +unsigned char *tostring(unsigned char *p, char *s); diff --git a/src/lib9p/dirto9p.c b/src/lib9p/dirto9p.c @@ -1,36 +0,0 @@ -#include <assert.h> - -#include <rcode/9p.h> - -#include "conv.h" - -int -dirto9p(Dir *dp, unsigned char *buf, int n) -{ - int len; - unsigned char *p; - - if (n < DIRLEN) - return 0; - - p = buf + 2; - SHORT(dp->type, p); /* type */ - LONG(dp->dev, p); /* dev */ - CHAR(dp->qid >> 8, p); /* qid.type */ - LONG(0, p); /* qid.vers */ - LLONG(dp->qid, p); /* qid.path */ - LONG(0, p); /* mode */ - LONG(0, p); /* atime */ - LONG(0, p); /* mtime */ - LLONG(dp->length, p); /* length */ - STRING(dp->name, p); /* name */ - STRING("root", p); /* uid */ - STRING("root", p); /* gid */ - STRING("root", p); /* muid */ - len = p -buf; - SHORT(len, buf); /* size */ - - assert(len < DIRLEN); - - return len; -} diff --git a/src/lib9p/dirtop9.c b/src/lib9p/dirtop9.c @@ -0,0 +1,36 @@ +#include <assert.h> + +#include <rcode/9p.h> + +#include "convto9p.h" + +int +dirto9p(Dir *dp, unsigned char *buf, int n) +{ + int len; + unsigned char *p; + + if (n < DIRLEN) + return 0; + + p = buf + 2; + SHORT(dp->type, p); /* type */ + LONG(dp->dev, p); /* dev */ + CHAR(dp->qid >> 8, p); /* qid.type */ + LONG(0, p); /* qid.vers */ + LLONG(dp->qid, p); /* qid.path */ + LONG(0, p); /* mode */ + LONG(0, p); /* atime */ + LONG(0, p); /* mtime */ + LLONG(dp->length, p); /* length */ + STRING("root", p); /* uid */ + STRING("root", p); /* gid */ + STRING("root", p); /* muid */ + STRING(dp->name, p); /* name */ + len = p - buf; + SHORT(len, buf); /* size */ + + assert(len < DIRLEN); + + return len; +} diff --git a/src/lib9p/frombytes.c b/src/lib9p/frombytes.c @@ -0,0 +1,24 @@ +#include "convfr9p.h" + +long long +frombytes(unsigned char *bp, int *n, int max, int nbytes) +{ + int i; + unsigned long long v; + + if (*n == -1) + return 0; + + if (*n + nbytes > max) { + *n = -1; + return -1; + } + + bp += *n; + *n += nbytes; + v = 0; + for (i = 0; i < nbytes; i++) + v |= bp[ i] << (8 * i); + + return v; +} diff --git a/src/lib9p/fromstring.c b/src/lib9p/fromstring.c @@ -0,0 +1,34 @@ +#include <string.h> + +#include "convfr9p.h" + +char * +fromstring(unsigned char *p, int *n, int max, char *s, int size) +{ + int len; + + if (*n == -1) + goto error; + + len = frombytes(p, n, max, 2); + if (len == -1) + goto error; + + if (*n + len > max) + goto error; + + if (len >= size) + goto error; + + if (s) { + memcpy(s, p + *n, len); + s[len] = '\0'; + } + *n += len; + + return s; + +error: + *n = -1; + return NULL; +} diff --git a/src/lib9p/p9todir.c b/src/lib9p/p9todir.c @@ -0,0 +1,40 @@ +#include <assert.h> +#include <stddef.h> + +#include <rcode/9p.h> + +#include "convfr9p.h" + +#define USED(x) ((void) x) +#define USERLEN 20 + +int +p9todir(Dir *dp, unsigned char *buf, int size) +{ + int n, len; + long l; + unsigned long long type, path; + + n = 0; + SHORT(len, buf, n, size); /* len */ + SHORT(dp->type, buf, n, size); /* type */ + LONG(dp->dev, buf, n, size); /* dev */ + CHAR(type, buf, n, size); /* qid.type */ + LONG(l, buf, n, size); /* qid.vers */ + LLONG(path, buf, n, size); /* qid.path */ + LONG(l, buf, n, size); /* mode */ + LONG(l, buf, n, size); /* atime */ + LONG(l, buf, n, size); /* mtime */ + LLONG(dp->length, buf, n, size); /* length */ + STRING(NULL, USERLEN, buf, n, size); /* uid */ + STRING(NULL, USERLEN, buf, n, size); /* gid */ + STRING(NULL, USERLEN, buf, n, size); /* muid */ + STRING(dp->name, NAMELEN, buf, n, size); /* name */ + USED(l); + + if (len != n) + return -1; + dp->qid = type << 8 | path; + + return n; +} diff --git a/src/lib9p/tobytes.c b/src/lib9p/tobytes.c @@ -1,4 +1,4 @@ -#include "conv.h" +#include "convto9p.h" unsigned char * tobytes(unsigned char *p, unsigned long long v, int n) diff --git a/src/lib9p/tostring.c b/src/lib9p/tostring.c @@ -1,6 +1,6 @@ #include <string.h> -#include "conv.h" +#include "convto9p.h" unsigned char * tostring(unsigned char *p, char *s) diff --git a/src/libk/Makefile b/src/libk/Makefile @@ -12,6 +12,9 @@ OBJS = doprnt.o \ kgets.o \ kerror.o \ putenv-$(MODE).o \ + kopendir.o \ + kreaddir.o \ + kclosedir.o \ __assert.o \ TARGET = $(LIBDIR)/libk.a diff --git a/src/libk/kclosedir.c b/src/libk/kclosedir.c @@ -0,0 +1,8 @@ +#include <libk.h> +#include <rcode/rcode.h> + +int +kclosedir(DIR *dir) +{ + return close(dir->fd); +} diff --git a/src/libk/kopendir.c b/src/libk/kopendir.c @@ -0,0 +1,20 @@ +#include <errno.h> + +#include <libk.h> +#include <rcode/rcode.h> + +DIR * +kopendir(DIR *dir, const char *name) +{ + int fd; + + if ((fd = open(name, O_READ)) < 0) { + errno = ENOENT; + return NULL; + } + dir->fd = fd; + + /* TODO: check that it is actually a directory */ + + return dir; +} diff --git a/src/libk/kreaddir.c b/src/libk/kreaddir.c @@ -0,0 +1,21 @@ +#include <string.h> + +#include <libk.h> +#include <rcode/rcode.h> + +struct dirent * +kreaddir(DIR *dir) +{ + int n; + Dir dentry; + + if ((n = read(dir->fd, dir->buf, sizeof(dir->buf))) < 0) + return NULL; + + if (p9todir(&dentry, dir->buf, n) < 0) + return NULL; + + strcpy(dir->ent.d_name, dentry.name); + + return &dir->ent; +} diff --git a/src/romfw/dlang.c b/src/romfw/dlang.c @@ -238,6 +238,24 @@ do_cat(const struct cmd *cmd, struct args *args) } static int +do_ls(const struct cmd *cmd, struct args *args) +{ + DIR dir; + struct dirent *d; + + if (!kopendir(&dir, args->argv[1])) + return -1; + + while ((d = kreaddir(&dir)) != NULL) + kprint(PREFIX "%s\n", d->d_name); + + if (kclosedir(&dir)) + return -1; + + return 0; +} + +static int do_chdir(const struct cmd *cmd, struct args *args) { return 0; @@ -411,6 +429,13 @@ static const struct cmd cmds[] = { .helpmsg = "change the current directory: cd path", }, { + .name = "ls", + .eval = do_ls, + .min = 2, + .max = 2, + .helpmsg = "list content of a directory: ls path", + }, + { .name = NULL } }; diff --git a/target/native/rom.c b/target/native/rom.c @@ -131,12 +131,10 @@ namespace(void) int fd; if (bind("#t", "/dev") < 0) - panic("openfds1"); + panic("namespace:bind"); - fd = open("/dev/uart0/raw", O_READ | O_WRITE); - - if (fd != 0) - panic("openfds2"); + if (open("/dev/uart0/raw", O_READ | O_WRITE) != 0) + panic("namespace:open"); } void