1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tests/dstest_file_client.cc Fri Jul 16 00:39:24 2021 +0200
1.3 @@ -0,0 +1,168 @@
1.4 +/*
1.5 + * Test file operations.
1.6 + *
1.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#include <l4/re/env.h>
1.26 +#include <l4/sys/err.h>
1.27 +
1.28 +#include <thread>
1.29 +
1.30 +#include <stdio.h>
1.31 +#include <string.h>
1.32 +#include <stdlib.h>
1.33 +
1.34 +#include <fsclient/client.h>
1.35 +#include <systypes/fcntl.h>
1.36 +
1.37 +
1.38 +
1.39 +/* Write data to the file. */
1.40 +
1.41 +static void write_data(file_t *file, int region)
1.42 +{
1.43 + offset_t size = 600;
1.44 + char buffer[size];
1.45 +
1.46 + memset(buffer, (int) 'a' + region, size);
1.47 +
1.48 + offset_t nwritten = client_write(file, buffer, size);
1.49 +
1.50 + printf("Written %ld/%ld in #%d to file with first %c, last %c...\n", nwritten, size, region, *buffer, *(buffer + nwritten - 1));
1.51 +
1.52 + /* Flush to make the output available. */
1.53 +
1.54 + client_flush(file);
1.55 +}
1.56 +
1.57 +/* Read and write data to the file. */
1.58 +
1.59 +static void read_and_write(file_t *file, bool creator)
1.60 +{
1.61 + offset_t size = 600, total = 0;
1.62 + long err;
1.63 + int region = 0;
1.64 +
1.65 + /* Register for notifications. */
1.66 +
1.67 + if ((err = client_subscribe(file, NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED)))
1.68 + {
1.69 + printf("Could not subscribe to notifications: %s\n", l4sys_errtostr(err));
1.70 + return;
1.71 + }
1.72 +
1.73 + /* Seek to the end of the file, if this is not actually a new file. */
1.74 +
1.75 + client_seek(file, 0, SEEK_END);
1.76 +
1.77 + printf("File %s at position %ld...\n", creator ? "creator" : "follower", client_tell(file));
1.78 +
1.79 + /* Write initial data as the file's creator. */
1.80 +
1.81 + if (creator)
1.82 + write_data(file, region++);
1.83 +
1.84 + while (region < 26)
1.85 + {
1.86 + char buffer[size];
1.87 + offset_t nread;
1.88 +
1.89 + /* Wait for notification of content. */
1.90 +
1.91 + err = client_wait_file(file);
1.92 +
1.93 + if (err)
1.94 + {
1.95 + printf("Error waiting for notifications: %s\n", l4sys_errtostr(err));
1.96 + return;
1.97 + }
1.98 +
1.99 + printf("File %s notified with conditions:%s%s\n", creator ? "creator" : "follower",
1.100 + file->notifications & NOTIFY_PEER_CLOSED ? " closed" : "",
1.101 + file->notifications & NOTIFY_CONTENT_AVAILABLE ? " content" : "");
1.102 +
1.103 + /* Attempt to read. */
1.104 +
1.105 + nread = client_read(file, buffer, size);
1.106 +
1.107 + while (nread)
1.108 + {
1.109 + total += nread;
1.110 +
1.111 + printf("Read as %s %ld/%ld, total %ld, first %c, last %c, from file...\n", creator ? "creator" : "follower",
1.112 + nread, size, total, *buffer, *(buffer + nread - 1));
1.113 +
1.114 + if (!(*(buffer + nread - 1)))
1.115 + printf("Warning: length before zero region is %ld\n", strlen(buffer));
1.116 +
1.117 +#if 0
1.118 + for (offset_t i = 0; i < nread; i += 60)
1.119 + {
1.120 + fwrite(buffer + i, sizeof(char), nread - i > 60 ? 60 : nread - i, stdout);
1.121 + fputs("\n", stdout);
1.122 + }
1.123 +#endif
1.124 + nread = client_read(file, buffer, size);
1.125 + }
1.126 +
1.127 + /* Without any more content, a peer closed event should terminate reading
1.128 + from the pipe. */
1.129 +
1.130 + if (file->notifications & NOTIFY_PEER_CLOSED)
1.131 + break;
1.132 +
1.133 + write_data(file, region++);
1.134 + }
1.135 +
1.136 + printf("Data shown.\n");
1.137 +}
1.138 +
1.139 +int main(int argc, char *argv[])
1.140 +{
1.141 + if (argc < 2)
1.142 + {
1.143 + printf("Need a filename.\n");
1.144 + return 1;
1.145 + }
1.146 +
1.147 + char *filename = argv[1];
1.148 +
1.149 + /* Invoke the open function to receive each file reference. */
1.150 +
1.151 + file_t *file1 = client_open(filename, O_RDWR); // | O_CREAT
1.152 + file_t *file2 = client_open(filename, O_RDWR);
1.153 +
1.154 + if ((file1 == NULL) || (file2 == NULL))
1.155 + {
1.156 + printf("Could not obtain files.\n");
1.157 + return 1;
1.158 + }
1.159 +
1.160 + /* Schedule threads. */
1.161 +
1.162 + std::thread *activities[2];
1.163 +
1.164 + activities[0] = new std::thread(read_and_write, file1, true);
1.165 + activities[1] = new std::thread(read_and_write, file2, false);
1.166 +
1.167 + for (int i = 0; i < 2; i++)
1.168 + activities[i]->join();
1.169 +}
1.170 +
1.171 +// vim: tabstop=2 expandtab shiftwidth=2