summaryrefslogtreecommitdiff
path: root/src/user/lib/fs/dir.c
diff options
context:
space:
mode:
authordzwdz2022-08-08 14:33:37 +0200
committerdzwdz2022-08-08 14:33:37 +0200
commit3131d8c2f66bcecb62dfa4c69325951cd9b00706 (patch)
tree595cb0baf29c15d75ffc94d04af71d7ae94517ed /src/user/lib/fs/dir.c
parentc7af8418c9a2222cde5ab3a6953b31803d0a8ef1 (diff)
fs: getsize() on directories
Diffstat (limited to 'src/user/lib/fs/dir.c')
-rw-r--r--src/user/lib/fs/dir.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/user/lib/fs/dir.c b/src/user/lib/fs/dir.c
index 802dd61..4235ea6 100644
--- a/src/user/lib/fs/dir.c
+++ b/src/user/lib/fs/dir.c
@@ -33,9 +33,11 @@ bool dir_appendl(struct dirbuild *db, const char *name, size_t len) {
len -= db->offset;
db->offset = 0;
- // TODO no buffer overrun check
- memcpy(db->buf + db->bpos, name, len - 1);
- db->buf[db->bpos + len - 1] = '\0';
+ if (db->buf) {
+ // TODO no buffer overrun check
+ memcpy(db->buf + db->bpos, name, len - 1);
+ db->buf[db->bpos + len - 1] = '\0';
+ }
db->bpos += len;
} else {
db->offset -= len;
@@ -45,26 +47,35 @@ bool dir_appendl(struct dirbuild *db, const char *name, size_t len) {
bool dir_append_from(struct dirbuild *db, handle_t h) {
if (db->error) return true;
+ if (db->buf && db->bpos == db->blen) return false;
- if (db->bpos == db->blen)
- return false;
+ int ret;
+ if (db->buf) {
+ ret = _syscall_read(h, db->buf + db->bpos, db->blen - db->bpos, db->offset);
+ if (ret < 0) {
+ db->error = ret;
+ return true;
+ } else if (ret > 0) {
+ /* not eof */
+ db->offset = 0;
+ db->bpos += ret;
+ return false;
+ } /* else ret == 0, EOF, need getsize */
+ }
- int ret = _syscall_read(h, db->buf + db->bpos, db->blen - db->bpos, db->offset);
+ ret = _syscall_getsize(h);
if (ret < 0) {
db->error = ret;
return true;
}
- if (ret == 0) {
- // TODO no idea how much we've overread
- // this messes up reading bind mounts of multiple directories
- db->error = -ENOSYS;
- return true;
+ if (db->offset < ret) {
+ /* should only occur when !buf, otherwise leaks previous data from buf.
+ * TODO consider impact */
+ db->bpos += ret - db->offset;
+ db->offset = 0;
+ } else {
+ db->offset -= ret;
}
-
- // TODO deduplicate entries
-
- db->offset = 0;
- db->bpos += ret;
return false;
}