1 /* 2 * Test directory reading operations, exploring concurrency issues. 3 * 4 * Copyright (C) 2020, 2021, 2022 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 #include <l4/re/env.h> 23 #include <l4/sys/err.h> 24 25 #include <stdio.h> 26 #include <string.h> 27 #include <stdlib.h> 28 29 #include <fsclient/client.h> 30 #include <systypes/fcntl.h> 31 32 33 34 static int count_files(const char *filename, int *found) 35 { 36 file_t *reader = client_opendir(filename); 37 struct dirent *dirent; 38 39 if (!client_opened(reader)) 40 { 41 client_close(reader); 42 return 1; 43 } 44 45 *found = 0; 46 47 while ((dirent = client_readdir(reader)) != NULL) 48 { 49 free(dirent); 50 (*found)++; 51 } 52 53 client_close(reader); 54 return 0; 55 } 56 57 int main(int argc, char *argv[]) 58 { 59 if (argc < 2) 60 { 61 printf("Need a directory name.\n"); 62 return 1; 63 } 64 65 char *filename = argv[1]; 66 int original; 67 68 if (count_files(filename, &original)) 69 { 70 printf("Could not read from directory.\n"); 71 return 1; 72 } 73 74 printf("Files found: %d\n", original); 75 76 /* Operate on files with sequence numbering in a certain range. */ 77 78 int filenum_base = 1000, filenum = filenum_base; 79 int to_create = 100, remaining = to_create; 80 char buffer[strlen(filename) + strlen("/file-XXXX.txt") + 10]; 81 char data[256]; 82 int found = 0; 83 file_t *files[to_create]; 84 85 /* Open a directory for reading. */ 86 87 printf("Opening %s...\n", filename); 88 89 file_t *reader = client_opendir(filename); 90 91 if (!client_opened(reader)) 92 { 93 client_close(reader); 94 printf("Could not read from directory.\n"); 95 return 1; 96 } 97 98 /* Read entries from the directory. */ 99 100 struct dirent *dirent; 101 102 printf("Reading...\n"); 103 104 while ((dirent = client_readdir(reader)) != NULL) 105 { 106 free(dirent); 107 found++; 108 109 /* Create files while getting the listing. */ 110 111 if (remaining) 112 { 113 sprintf(buffer, "%s/file-%d.txt", filename, filenum); 114 115 file_t *file = client_open(buffer, O_RDWR | O_CREAT); 116 117 if (!client_opened(file)) 118 { 119 client_close(file); 120 printf("Could not open file: %s\n", buffer); 121 return 1; 122 } 123 124 /* Write something to each file. */ 125 126 sprintf(data, "Data in file-%d.txt", filenum); 127 client_write(file, data, strlen(data)); 128 129 /* Remember the file for later. */ 130 131 files[filenum - filenum_base] = file; 132 133 remaining--; 134 filenum++; 135 } 136 } 137 138 printf("Files found: %d\n", found); 139 140 /* Re-read, counting files. */ 141 142 if (count_files(filename, &found)) 143 { 144 printf("Could not read from directory.\n"); 145 return 1; 146 } 147 148 printf("Files found: %d\n", found); 149 150 /* Remove some files. */ 151 152 for (filenum = 1000, remaining = to_create; remaining > 0; remaining--, filenum++) 153 { 154 sprintf(buffer, "%s/file-%d.txt", filename, filenum); 155 156 long err = client_remove(buffer); 157 158 if (err) 159 { 160 printf("Could not remove file: %s\n", buffer); 161 return 1; 162 } 163 } 164 165 /* Re-read, counting files. */ 166 167 if (count_files(filename, &found)) 168 { 169 printf("Could not read from directory.\n"); 170 return 1; 171 } 172 173 printf("Files found: %d\n", found); 174 175 /* Read from the still-open but now removed files. */ 176 177 found = 0; 178 179 for (filenum = 1000, remaining = 0; remaining < to_create; remaining++, filenum++) 180 { 181 file_t *file = files[filenum - filenum_base]; 182 char read_data[256]; 183 184 client_seek(file, SEEK_SET, 0); 185 offset_t nread = client_read(file, read_data, 256); 186 187 if (nread) 188 { 189 read_data[nread] = '\0'; 190 sprintf(data, "Data in file-%d.txt", filenum); 191 192 if (!strcmp(data, read_data)) 193 found++; 194 } 195 } 196 197 printf("Files still open: %d (%d)\n", found, to_create); 198 printf("All created files still open: %s\n", found == to_create ? "True" : "False"); 199 200 /* Close the files. */ 201 202 for (remaining = 0; remaining < to_create; remaining++) 203 client_close(files[remaining]); 204 205 printf("Closed files.\n"); 206 207 /* Re-read, counting files. */ 208 209 if (count_files(filename, &found)) 210 { 211 printf("Could not read from directory.\n"); 212 return 1; 213 } 214 215 printf("Files found: %d (%d)\n", found, original); 216 printf("Removed all surplus files: %s\n", found == original ? "True" : "False"); 217 printf("End of test.\n"); 218 return 0; 219 } 220 221 // vim: tabstop=2 expandtab shiftwidth=2