9os

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

commit 2a246405c053e425bd04ea2945bc5d2e642294c8
parent 8e03e0ea337ea4eca6c8d905062bbacb6dffb9c3
Author: Ambroise Vincent <ambroise.vincent@arm.com>
Date:   Thu,  9 May 2019 14:32:07 +0100

[dev] Fix stat and dirstat

Change-Id: Ic127837d09ccf3af695bf62d8fbf7377fcddfa1d
Signed-off-by: Ambroise Vincent <ambroise.vincent@arm.com>

Diffstat:
Mdrivers/dev.c | 36+++++++++++++++++++++++-------------
Mdrivers/devfip.c | 2+-
Minclude/string.h | 1+
Msrc/lib9p/dirstat.c | 4++--
4 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/drivers/dev.c b/drivers/dev.c @@ -139,7 +139,7 @@ buf2chan(Chan *c, void *dst, void *src, int nbytes, long len) } static Chan * -mntpoint(Chan *c) +mntpoint(int type, Qid qid) { Chan *cn; struct mpoint *mp; @@ -147,7 +147,7 @@ mntpoint(Chan *c) for (mp = mpoints; mp < &mpoints[NR_MPOINTS]; mp++) { if ((cn = mp->new) == NULL) continue; - if (cn->type == c->type && cn->qid == c->qid) + if (cn->type == type && cn->qid == qid) return mp->old; } @@ -221,7 +221,7 @@ namec(const char *name, int mode) chanclose(c); return NULL; } - mnt = mntpoint(c); + mnt = mntpoint(c->type, c->qid); if (mnt) clone(mnt, c); } @@ -367,7 +367,7 @@ devstat(Chan *dirc, char *file, { int i, r = -1; Dir dir; - Chan *c; + Chan *c, *mnt; if ((c = namec(file, O_STAT)) == NULL) return -1; @@ -380,7 +380,12 @@ devstat(Chan *dirc, char *file, r = -1; goto leave; case 1: - if (dir.qid != c->qid) + mnt = mntpoint(dir.type, dir.qid); + if (mnt) { + dir.qid = mnt->qid; + dir.type = mnt->type; + } + if (dir.qid != c->qid || dir.type != c->type) continue; r = dirtop9(&dir, buf, n); goto leave; @@ -400,23 +405,28 @@ stat(char *path, void *buf, int n) Chan *c; char *p, dirname[NAMELEN]; - if (n < STATLEN) { + if (n < DIRLEN) { errno = EINVAL; return -1; } - p = strrchr(path, '/'); - if (!p) { - errno = ENOENT; + len = strlen(path); + if (len + 1 > sizeof(dirname)) { + errno = ENAMETOOLONG; return -1; } + memcpy(dirname, path, len); + for (p = dirname + len; p > dirname; --p) { + if (*p != '/') + break; + } - if ((len = p - path) > NAMELEN-1) { - errno = EINVAL; + p = memrchr(dirname, '/', p - dirname); + if (!p) { + errno = ENOENT; return -1; } - memcpy(dirname, path, len); - dirname[len] = '\0'; + dirname[p - dirname + 1] = '\0'; if ((c = namec(dirname, O_STAT)) == NULL) return -1; diff --git a/drivers/devfip.c b/drivers/devfip.c @@ -153,7 +153,7 @@ fipwalk(Chan *c, const char *name) } static int -fipstat((Chan *c, char *file, unsigned char *buf, int n) +fipstat(Chan *c, char *file, unsigned char *buf, int n) { return devstat(c, file, buf, n, NULL, 0, fipgen); } diff --git a/include/string.h b/include/string.h @@ -19,6 +19,7 @@ extern int strcoll(const char *s1, const char *s2); extern int strncmp(const char *s1, const char *s2, size_t n); extern size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n); extern void *memchr(const void *s, int c, size_t n); +extern void *memrchr(const void *s, int c, size_t n); extern char *strchr(const char *s, int c); extern size_t strcspn(const char *s1, const char *s2); extern char *strpbrk(const char *s1, const char *s2); diff --git a/src/lib9p/dirstat.c b/src/lib9p/dirstat.c @@ -4,10 +4,10 @@ int dirstat(char *name, Dir *dir) { - unsigned char buf[STATLEN]; + unsigned char buf[DIRLEN]; int n; - if ((n = stat(name, buf, STATLEN)) < 0) + if ((n = stat(name, buf, sizeof(buf))) < 0) return -1; if (p9todir(dir, buf, n) < 0)