1 /* 2 * Test directory monitoring operations. 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 <thread> 26 27 #include <stdio.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 32 #include <fsclient/client.h> 33 #include <systypes/fcntl.h> 34 35 36 37 /* Number of files to open in the test. */ 38 39 static const int FILES_TO_OPEN = 10; 40 41 42 43 /* Open files in the directory given by filename. */ 44 45 static void open_files(const char *filename) 46 { 47 char *buffer = (char *) calloc(strlen(filename) + 10, sizeof(char)); 48 49 if (buffer == NULL) 50 { 51 printf("Could not allocate buffer.\n"); 52 return; 53 } 54 55 for (int i = 0; i < FILES_TO_OPEN; i++) 56 { 57 sprintf(buffer, "%s/file%02d", filename, i); 58 59 client_open(buffer, O_CREAT | O_RDWR); 60 sleep(1); 61 } 62 } 63 64 /* Monitor files in the given directory. */ 65 66 static void monitor_files(file_t *directory) 67 { 68 long err = client_subscribe(directory, NOTIFY_FILE_OPENED, client_notifier_task()); 69 70 if (err) 71 { 72 printf("Could not subscribe to events on directory.\n"); 73 return; 74 } 75 76 int expected; 77 78 for (expected = FILES_TO_OPEN; expected; expected--) 79 { 80 /* Wait for notification of content. */ 81 82 err = client_wait_file(directory, client_notifier_task()); 83 84 if (err) 85 { 86 printf("Error waiting for notifications: %s\n", l4sys_errtostr(err)); 87 return; 88 } 89 90 printf("Notified with conditions:%s\n", directory->notifications & NOTIFY_FILE_OPENED ? " file opened" : ""); 91 } 92 93 printf("Notified for all expected files: %s\n", expected ? "False" : "True"); 94 } 95 96 97 98 int main(int argc, char *argv[]) 99 { 100 if (argc < 2) 101 { 102 printf("Need a directory name.\n"); 103 return 1; 104 } 105 106 char *filename = argv[1]; 107 108 printf("Opening %s...\n", filename); 109 110 file_t *directory = client_open(filename, O_DIRECTORY); 111 112 if (!client_opened(directory)) 113 { 114 client_close(directory); 115 printf("Could not open directory.\n"); 116 return 1; 117 } 118 119 /* Schedule threads. */ 120 121 std::thread *activities[2]; 122 123 activities[0] = new std::thread(open_files, filename); 124 activities[1] = new std::thread(monitor_files, directory); 125 126 for (int i = 0; i < 2; i++) 127 activities[i]->join(); 128 129 printf("Expected %d 'file opened' notifications.\n", FILES_TO_OPEN); 130 printf("End of test.\n"); 131 return 0; 132 } 133 134 // vim: tabstop=2 expandtab shiftwidth=2