1.1 --- a/libfsserver/lib/files/host_file_opener.cc Wed Aug 04 17:13:47 2021 +0200
1.2 +++ b/libfsserver/lib/files/host_file_opener.cc Wed Aug 04 17:30:14 2021 +0200
1.3 @@ -19,11 +19,50 @@
1.4 * Boston, MA 02110-1301, USA
1.5 */
1.6
1.7 +#include <thread>
1.8 +
1.9 +#include <dirent.h>
1.10 #include <sys/stat.h>
1.11
1.12 +#include <fsclient/client.h>
1.13 +
1.14 #include "host_file_accessor.h"
1.15 #include "host_file_opener.h"
1.16
1.17 +
1.18 +
1.19 +/* Thread payload. */
1.20 +
1.21 +static void read_directory(const char *path, file_t *writer)
1.22 +{
1.23 + DIR *dir = opendir(path);
1.24 + struct dirent *dirent;
1.25 +
1.26 + /* Subscribe to space and closure notifications on the pipe. */
1.27 +
1.28 + long err = client_set_blocking(writer, NOTIFY_SPACE_AVAILABLE);
1.29 +
1.30 + if (err)
1.31 + {
1.32 + client_close(writer);
1.33 + return;
1.34 + }
1.35 +
1.36 + /* Write directory entries to the pipe, closing the pipe when finished. */
1.37 +
1.38 + while ((dirent = readdir(dir)) != NULL)
1.39 + {
1.40 + offset_t nwritten = 0;
1.41 +
1.42 + while (nwritten < dirent->d_reclen)
1.43 + nwritten += client_write(writer, (const void *) (dirent + nwritten), dirent->d_reclen - nwritten);
1.44 + }
1.45 +
1.46 + client_close(writer);
1.47 +}
1.48 +
1.49 +
1.50 +
1.51 HostFileOpener::~HostFileOpener()
1.52 {
1.53 }
1.54 @@ -50,6 +89,33 @@
1.55 return (st.st_mode & S_IFREG) ? true : false;
1.56 }
1.57
1.58 +long HostFileOpener::get_directory(const char *path, flags_t flags, fileid_t fileid, offset_t *size, l4_cap_idx_t *cap)
1.59 +{
1.60 + file_t *reader, *writer;
1.61 +
1.62 + // NOTE: Might be more appropriate to use lower-level file operations to
1.63 + // NOTE: avoid unnecessary mapping of the reader's memory region.
1.64 +
1.65 + long err = client_pipe(&reader, &writer);
1.66 +
1.67 + if (err)
1.68 + return err;
1.69 +
1.70 + *size = reader->size;
1.71 + *cap = reader->ref;
1.72 +
1.73 + /* Discard the reader structure but do not close the reader itself. */
1.74 +
1.75 + delete reader;
1.76 +
1.77 + /* Spawn a independent thread for reading the directory details and writing
1.78 + them to the pipe. */
1.79 +
1.80 + std::thread(read_directory, path, writer).detach();
1.81 +
1.82 + return L4_EOK;
1.83 +}
1.84 +
1.85 /* Return a file identifier for the given 'path'. */
1.86
1.87 long HostFileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid)