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 (reader == NULL) 40 return 1; 41 42 *found = 0; 43 44 while ((dirent = client_readdir(reader)) != NULL) 45 { 46 free(dirent); 47 (*found)++; 48 } 49 50 client_close(reader); 51 return 0; 52 } 53 54 int main(int argc, char *argv[]) 55 { 56 if (argc < 2) 57 { 58 printf("Need a directory name.\n"); 59 return 1; 60 } 61 62 char *filename = argv[1]; 63 int original; 64 65 if (count_files(filename, &original)) 66 { 67 printf("Could not read from directory.\n"); 68 return 1; 69 } 70 71 printf("Files found: %d\n", original); 72 73 struct dirent *dirent; 74 int filenum_base = 1000, filenum = filenum_base; 75 int to_create = 100, remaining = to_create; 76 char buffer[strlen(filename) + strlen("/file-XXXX.txt") + 10]; 77 char data[256]; 78 int found = 0; 79 file_t *files[to_create]; 80 81 printf("Opening %s...\n", filename); 82 83 file_t *reader = client_opendir(filename); 84 85 if (reader == NULL) 86 { 87 printf("Could not read from directory.\n"); 88 return 1; 89 } 90 91 printf("Reading...\n"); 92 93 while ((dirent = client_readdir(reader)) != NULL) 94 { 95 free(dirent); 96 found++; 97 98 /* Create files while getting the listing. */ 99 100 if (remaining) 101 { 102 sprintf(buffer, "%s/file-%d.txt", filename, filenum); 103 104 file_t *file = client_open(buffer, O_RDWR | O_CREAT); 105 106 if (file == NULL) 107 { 108 printf("Could not open file: %s\n", buffer); 109 return 1; 110 } 111 112 /* Write something to each file. */ 113 114 sprintf(data, "Data in file-%d.txt", filenum); 115 client_write(file, data, strlen(data)); 116 117 /* Remember the file for later. */ 118 119 files[filenum - filenum_base] = file; 120 121 remaining--; 122 filenum++; 123 } 124 } 125 126 printf("Files found: %d\n", found); 127 128 /* Re-read, counting files. */ 129 130 if (count_files(filename, &found)) 131 { 132 printf("Could not read from directory.\n"); 133 return 1; 134 } 135 136 printf("Files found: %d\n", found); 137 138 /* Remove some files. */ 139 140 for (filenum = 1000, remaining = to_create; remaining > 0; remaining--, filenum++) 141 { 142 sprintf(buffer, "%s/file-%d.txt", filename, filenum); 143 144 long err = client_remove(buffer); 145 146 if (err) 147 { 148 printf("Could not remove file: %s\n", buffer); 149 return 1; 150 } 151 } 152 153 /* Re-read, counting files. */ 154 155 if (count_files(filename, &found)) 156 { 157 printf("Could not read from directory.\n"); 158 return 1; 159 } 160 161 printf("Files found: %d\n", found); 162 163 /* Read from the still-open but now removed files. */ 164 165 found = 0; 166 167 for (filenum = 1000, remaining = 0; remaining < to_create; remaining++, filenum++) 168 { 169 file_t *file = files[filenum - filenum_base]; 170 char read_data[256]; 171 172 client_seek(file, SEEK_SET, 0); 173 offset_t nread = client_read(file, read_data, 256); 174 175 if (nread) 176 { 177 read_data[nread] = '\0'; 178 sprintf(data, "Data in file-%d.txt", filenum); 179 180 if (!strcmp(data, read_data)) 181 found++; 182 } 183 } 184 185 printf("Files still open: %d (%d)\n", found, to_create); 186 187 /* Close the files. */ 188 189 for (remaining = 0; remaining < to_create; remaining++) 190 client_close(files[remaining]); 191 192 printf("Closed files.\n"); 193 194 /* Re-read, counting files. */ 195 196 if (count_files(filename, &found)) 197 { 198 printf("Could not read from directory.\n"); 199 return 1; 200 } 201 202 printf("Files found: %d (%d)\n", found, original); 203 204 return 0; 205 } 206 207 // vim: tabstop=2 expandtab shiftwidth=2