# HG changeset patch # User Paul Boddie # Date 1628631717 -7200 # Node ID 10bc1e2cb24460870932f9ab2c53b859d59b7541 # Parent df6cf32a9ac8c34c2db7e506277f608ec99fdb5d Introduced a client function for reading directory entries. diff -r df6cf32a9ac8 -r 10bc1e2cb244 libfsclient/include/fsclient/client.h --- a/libfsclient/include/fsclient/client.h Tue Aug 10 23:41:21 2021 +0200 +++ b/libfsclient/include/fsclient/client.h Tue Aug 10 23:41:57 2021 +0200 @@ -21,6 +21,7 @@ #pragma once +#include #include @@ -61,6 +62,10 @@ offset_t client_seek(file_t *file, offset_t offset, int whence); long client_tell(file_t *file); +/* Directory reading operations. */ + +struct dirent *client_readdir(file_t *file); + /* Notification operations. */ long client_set_blocking(file_t *file, notify_flags_t flags); diff -r df6cf32a9ac8 -r 10bc1e2cb244 libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Tue Aug 10 23:41:21 2021 +0200 +++ b/libfsclient/lib/src/client.cc Tue Aug 10 23:41:57 2021 +0200 @@ -23,6 +23,7 @@ #include #include +#include #include "client.h" @@ -32,6 +33,10 @@ const offset_t DEFAULT_PIPE_SIZE = 4096; +/* Size of the core member region of a directory entry structure. */ + +const offset_t DIRENT_CORE_SIZE = (sizeof(struct dirent) - sizeof(((struct dirent *) 0)->d_name)); + /* Access the given position and synchronise state with the file object. Pipe @@ -271,6 +276,18 @@ +/* Obtain the current region of a pipe. */ + +long client_current_region(file_t *file) +{ + if (file == NULL) + return -L4_EINVAL; + + return pipe_current(file); +} + + + /* Flush data explicitly to the filesystem object. */ long client_flush(file_t *file) @@ -297,18 +314,6 @@ -/* Obtain the current region of a pipe. */ - -long client_current_region(file_t *file) -{ - if (file == NULL) - return -L4_EINVAL; - - return pipe_current(file); -} - - - /* Obtain the next region of a pipe. */ long client_next_region(file_t *file) @@ -321,6 +326,51 @@ +/* Read a directory entry. This must be freed by the caller after use. */ + +struct dirent *client_readdir(file_t *file) +{ + char buffer[DIRENT_CORE_SIZE]; + offset_t nread = client_read(file, buffer, DIRENT_CORE_SIZE); + + /* Stop if no new structure can be successfully read. */ + + if (nread != DIRENT_CORE_SIZE) + return NULL; + + struct dirent *dirent = (struct dirent *) buffer; + offset_t remaining = dirent->d_reclen - DIRENT_CORE_SIZE; + + /* Allocate a buffer for the complete structure. */ + + char *entry = (char *) calloc(DIRENT_CORE_SIZE + remaining, sizeof(char)); + + if (entry == NULL) + return NULL; + + /* Copy the start of the entry into a new buffer. */ + + memcpy(entry, buffer, DIRENT_CORE_SIZE); + + /* Append to the entry buffer. */ + + char *current = entry + DIRENT_CORE_SIZE; + + nread = client_read(file, current, remaining); + + /* Stop if no complete structure can be successfully read. */ + + if (nread != remaining) + { + free(entry); + return NULL; + } + + return (struct dirent *) entry; +} + + + /* Read from the filesystem object into the buffer provided. */ offset_t client_read(file_t *file, void *buf, offset_t count) diff -r df6cf32a9ac8 -r 10bc1e2cb244 tests/dstest_file_readdir.cc --- a/tests/dstest_file_readdir.cc Tue Aug 10 23:41:21 2021 +0200 +++ b/tests/dstest_file_readdir.cc Tue Aug 10 23:41:57 2021 +0200 @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -32,55 +31,6 @@ -#define DIRENT_CORE_SIZE (sizeof(struct dirent) - sizeof(((struct dirent *) 0)->d_name)) - - - -/* Return a directory entry. This must be freed by the caller after use. */ - -static struct dirent *read_directory_entry(file_t *file) -{ - char buffer[DIRENT_CORE_SIZE]; - offset_t nread = client_read(file, buffer, DIRENT_CORE_SIZE); - - /* Stop if no new structure can be successfully read. */ - - if (nread != DIRENT_CORE_SIZE) - return NULL; - - struct dirent *dirent = (struct dirent *) buffer; - offset_t remaining = dirent->d_reclen - DIRENT_CORE_SIZE; - - /* Allocate a buffer for the complete structure. */ - - char *entry = (char *) calloc(DIRENT_CORE_SIZE + remaining, sizeof(char)); - - if (entry == NULL) - return NULL; - - /* Copy the start of the entry into a new buffer. */ - - memcpy(entry, buffer, DIRENT_CORE_SIZE); - - /* Append to the entry buffer. */ - - char *current = entry + DIRENT_CORE_SIZE; - - nread = client_read(file, current, remaining); - - /* Stop if no complete structure can be successfully read. */ - - if (nread != remaining) - { - free(entry); - return NULL; - } - - return (struct dirent *) entry; -} - - - static file_t *open_file(char *filename, bool have_uid, sys_uid_t uid) { /* With a user, open a user-specific file opener. */ @@ -145,7 +95,7 @@ struct dirent *dirent; - while ((dirent = read_directory_entry(file)) != NULL) + while ((dirent = client_readdir(file)) != NULL) { printf("> %s\n", dirent->d_name); free(dirent); @@ -171,7 +121,7 @@ return 1; } - dirent = read_directory_entry(file); + dirent = client_readdir(file); if (dirent != NULL) {