1 /* 2 * A filesystem directory resource. 3 * 4 * Copyright (C) 2018, 2019 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #pragma once 23 24 #include <l4/sys/types.h> 25 26 #include <dirent.h> 27 #include <pthread.h> 28 #include <stdio.h> 29 #include <sys/stat.h> 30 31 #include <ext2fs/ext2fs.h> 32 #include <ipc/message.h> 33 34 /* Employed interface. */ 35 36 #include "directory_listing_private_interface.h" 37 38 39 40 /* Utility macros. */ 41 42 #define DIRENT_CORE_SIZE (sizeof(struct dirent) - sizeof(((struct dirent *) 0)->d_name)) 43 44 45 46 /* Entry structure. */ 47 48 struct entry 49 { 50 /* Details of the entry provided during iteration. */ 51 52 struct ext2_dir_entry *dir_entry; 53 54 /* Name and total entry sizes. The total entry size must be aligned for the 55 architecture. This ensures that the serialised stat buffer is aligned. */ 56 57 int namelen; 58 int reclen; 59 60 /* Structure for population when providing metadata. */ 61 62 struct stat statbuf; 63 64 /* Total size of the copied details. This must be aligned for the architecture 65 for convenient access to the details as structures. */ 66 67 int size; 68 }; 69 70 71 72 /* Filesystem directory resource employing an interface for private use by the 73 server. */ 74 75 class Fs_directory_listing : public DirectoryListingPrivate 76 { 77 private: 78 ext2_filsys _fs; 79 ext2_ino_t _dir; 80 int _flags; 81 82 /* Transfer buffer. */ 83 84 char *_buffer; 85 size_t _buffer_size; 86 87 /* Reading state. */ 88 89 size_t _seek_pos, _start_pos, _index; 90 91 /* Concurrency and communication. */ 92 93 pthread_t _thread; 94 l4_cap_idx_t _thread_ep; 95 bool _terminating; 96 97 public: 98 explicit Fs_directory_listing(ext2_filsys fs, ext2_ino_t dir, int flags=0) 99 : _fs(fs), _dir(dir), _flags(flags) { } 100 101 virtual ~Fs_directory_listing() { } 102 103 /* Activation. */ 104 105 long start(); 106 107 /* Deallocation of resources. */ 108 109 void close(); 110 111 /* Accessor-operated methods. */ 112 113 size_t read_into(size_t start, char *buffer, size_t length); 114 115 /* Thread mainloop. */ 116 117 void mainloop(); 118 119 /* Callback method for directory entry processing. */ 120 121 int record_entry(struct ext2_dir_entry *dir_entry); 122 123 /* Entry handling for output. */ 124 125 void init_entry(struct entry *entry, struct ext2_dir_entry *dir_entry); 126 127 /* Record writing methods. */ 128 129 int add_null_entry(); 130 void _copy_entry(char *out, struct entry *entry); 131 void copy_entry(struct entry *entry); 132 void copy_entry_start(struct entry *entry, int size); 133 void copy_entry_end(struct entry *entry, int offset); 134 135 /* Concurrency methods. */ 136 137 void _wait(); 138 void _yield(size_t size); 139 140 /* IPC operation methods. */ 141 142 virtual long read(size_t position); 143 virtual long terminate(); 144 145 protected: 146 /* Reply to requests for results. */ 147 148 void reply(); 149 };