1.1 --- a/libfsclient/include/fsclient/file.h Sat May 01 01:46:33 2021 +0200
1.2 +++ b/libfsclient/include/fsclient/file.h Sat May 01 22:37:16 2021 +0200
1.3 @@ -55,6 +55,10 @@
1.4
1.5 int can_mmap;
1.6
1.7 + /* Explicit size support. */
1.8 +
1.9 + int has_size;
1.10 +
1.11 } file_t;
1.12
1.13
2.1 --- a/libfsclient/lib/src/client.cc Sat May 01 01:46:33 2021 +0200
2.2 +++ b/libfsclient/lib/src/client.cc Sat May 01 22:37:16 2021 +0200
2.3 @@ -126,9 +126,11 @@
2.4
2.5 /* Strict conditions for region navigation in pipes. */
2.6
2.7 - else if ((position != file->end_pos) ||
2.8 - (client_next_region(file) == NULL))
2.9 - return -L4_EIO;
2.10 + else
2.11 + {
2.12 + if ((position != file->end_pos) || (client_next_region(file) == NULL))
2.13 + return -L4_EIO;
2.14 + }
2.15 }
2.16
2.17 /* Otherwise, flush any written data in the current region and update the
2.18 @@ -136,15 +138,26 @@
2.19
2.20 else
2.21 {
2.22 - err = client_flush(file);
2.23 -
2.24 - if (err)
2.25 - return err;
2.26 + if (file->can_mmap)
2.27 + {
2.28 + err = client_flush(file);
2.29 + if (err)
2.30 + return err;
2.31 + }
2.32 + else
2.33 + {
2.34 + if (client_current_region(file) == NULL)
2.35 + return -L4_EIO;
2.36 + }
2.37 }
2.38
2.39 /* Update the current data offset. */
2.40
2.41 - file->data_current = position - file->start_pos;
2.42 + if (file->has_size)
2.43 + file->data_current = position - file->start_pos;
2.44 + else
2.45 + file->data_current = 0;
2.46 +
2.47 return L4_EOK;
2.48 }
2.49
2.50 @@ -200,6 +213,24 @@
2.51
2.52
2.53
2.54 +/* Ensure that memory is mapped for accessing the given file, using the
2.55 + indicated count as a region size hint. */
2.56 +
2.57 +static void *_map_memory(file_t *file, offset_t count)
2.58 +{
2.59 + if (file->memory == NULL)
2.60 + {
2.61 + if (file->can_mmap)
2.62 + return client_mmap(file, client_tell(file), count);
2.63 + else if (pipe_current(file))
2.64 + return NULL;
2.65 + }
2.66 +
2.67 + return file->memory;
2.68 +}
2.69 +
2.70 +
2.71 +
2.72 /* Read from the filesystem object into the buffer provided. */
2.73
2.74 offset_t client_read(file_t *file, void *buf, offset_t count)
2.75 @@ -209,7 +240,7 @@
2.76
2.77 /* Map memory if none has been mapped so far. */
2.78
2.79 - if ((file->memory == NULL) && (client_mmap(file, client_tell(file), count) == NULL))
2.80 + if (_map_memory(file, count) == NULL)
2.81 return 0;
2.82
2.83 /* Amount available in the descriptor buffer already. */
2.84 @@ -348,7 +379,7 @@
2.85
2.86 /* Map memory if none has been mapped so far. */
2.87
2.88 - if ((file->memory == NULL) && (client_mmap(file, client_tell(file), count) == NULL))
2.89 + if (_map_memory(file, count) == NULL)
2.90 return 0;
2.91
2.92 /* Attempt to ensure that the file can accept the amount of data to be
2.93 @@ -357,12 +388,15 @@
2.94
2.95 offset_t needed_size = file_data_current_position(file) + count;
2.96
2.97 - if (file->size < needed_size)
2.98 + if (file->has_size)
2.99 {
2.100 - file_resize(file, needed_size);
2.101 + if (file->size < needed_size)
2.102 + {
2.103 + file_resize(file, needed_size);
2.104
2.105 - if (file->size < needed_size)
2.106 - count = file->size - file_data_current_position(file);
2.107 + if (file->size < needed_size)
2.108 + count = file->size - file_data_current_position(file);
2.109 + }
2.110 }
2.111
2.112 /* Space remaining in the descriptor buffer. */
3.1 --- a/libfsclient/lib/src/file.cc Sat May 01 01:46:33 2021 +0200
3.2 +++ b/libfsclient/lib/src/file.cc Sat May 01 22:37:16 2021 +0200
3.3 @@ -70,6 +70,7 @@
3.4 file->data_end = 0;
3.5 file->data_current = 0;
3.6 file->can_mmap = 1;
3.7 + file->has_size = 1;
3.8 }
3.9
3.10
3.11 @@ -202,6 +203,9 @@
3.12
3.13 long file_resize(file_t *file, offset_t size)
3.14 {
3.15 + if (!file->has_size)
3.16 + return -L4_EIO;
3.17 +
3.18 client_File _file(file->ref);
3.19 offset_t file_size = size;
3.20 long err = _file.resize(&file_size);
3.21 @@ -372,7 +376,9 @@
3.22 /* Pipes can usually only be accessed via region navigation. */
3.23
3.24 reader->can_mmap = 0;
3.25 + reader->has_size = 0;
3.26 writer->can_mmap = 0;
3.27 + writer->has_size = 0;
3.28
3.29 long err = opener.pipe(size, &reader->ref, &writer->ref);
3.30 if (err)
4.1 --- a/tests/dstest_pipe_client.cc Sat May 01 01:46:33 2021 +0200
4.2 +++ b/tests/dstest_pipe_client.cc Sat May 01 22:37:16 2021 +0200
4.3 @@ -26,33 +26,12 @@
4.4 #include <string.h>
4.5 #include <stdlib.h>
4.6
4.7 +#include <fsclient/client.h>
4.8 #include <fsclient/file.h>
4.9 #include <mem/memory_utils.h>
4.10
4.11
4.12
4.13 -static void show(file_t *file, offset_t step, offset_t sample)
4.14 -{
4.15 - /* Allocate a buffer for sampling from the file. */
4.16 -
4.17 - char buf[sample + 1];
4.18 -
4.19 - for (offset_t offset = 0; offset < file_populated_span(file); offset += step)
4.20 - {
4.21 - printf("show %ld of %ld...\n", offset, file_populated_span(file));
4.22 -
4.23 - unsigned long remaining = file_populated_span(file) - offset;
4.24 - unsigned long sample_remaining = remaining < sample ? remaining : sample;
4.25 -
4.26 - printf("%ld bytes from %p...\n", sample_remaining, (file->memory + offset));
4.27 - strncpy(buf, (file->memory + offset), sample_remaining);
4.28 - buf[sample_remaining] = '\0';
4.29 - printf("%s\n", buf);
4.30 - }
4.31 -}
4.32 -
4.33 -
4.34 -
4.35 const unsigned int PIPE_PAGES = 2;
4.36
4.37 int main(void)
4.38 @@ -74,45 +53,58 @@
4.39
4.40 /* Use the writer to fill the pipe with data. */
4.41
4.42 - for (int region = 0; region < 3; region++)
4.43 + offset_t size = 600;
4.44 + char buffer[size];
4.45 + int region = 0;
4.46 +
4.47 + for (int loop = 0; loop < 3; loop++)
4.48 {
4.49 - printf("Write %ld to pipe at %p...\n", file_span(&writer), writer.memory);
4.50 + while (1)
4.51 + {
4.52 + printf("Writing %ld to pipe...\n", size);
4.53
4.54 - memset(writer.memory, (int) 'a' + region, file_span(&writer));
4.55 + memset(buffer, (int) 'a' + region, size);
4.56 +
4.57 + offset_t nwritten = client_write(&writer, buffer, size);
4.58
4.59 - err = pipe_written(&writer, file_span(&writer));
4.60 + printf("Written %ld to pipe...\n", nwritten);
4.61 +
4.62 + for (offset_t i = 0; i < nwritten; i += 60)
4.63 + {
4.64 + fwrite(buffer + i, sizeof(char), nwritten - i > 60 ? 60 : nwritten - i, stdout);
4.65 + fputs("\n", stdout);
4.66 + }
4.67
4.68 - if (err)
4.69 - {
4.70 - printf("Written data error: %s\n", l4sys_errtostr(err));
4.71 - return 1;
4.72 + if (!nwritten)
4.73 + break;
4.74 +
4.75 + region++;
4.76 +
4.77 + if (region == 26)
4.78 + region = 0;
4.79 }
4.80
4.81 - show(&writer, page(1), 60);
4.82 + /* Use the reader to obtain data from the pipe. */
4.83
4.84 - err = pipe_next(&writer);
4.85 + offset_t nread;
4.86
4.87 - if (err)
4.88 + do
4.89 {
4.90 - printf("Region traversal error at region %d: %s\n", region, l4sys_errtostr(err));
4.91 - break;
4.92 - }
4.93 - }
4.94 + printf("Reading %ld from pipe...\n", size);
4.95 +
4.96 + nread = client_read(&reader, buffer, size);
4.97
4.98 - /* Use the reader to obtain data from the pipe. */
4.99 -
4.100 - err = pipe_current(&reader);
4.101 + printf("Read %ld from pipe...\n", nread);
4.102
4.103 - while (!err)
4.104 - {
4.105 - printf("show...\n");
4.106 - show(&reader, page(1), 60);
4.107 - err = pipe_next(&reader);
4.108 + for (offset_t i = 0; i < nread; i += 60)
4.109 + {
4.110 + fwrite(buffer + i, sizeof(char), nread - i > 60 ? 60 : nread - i, stdout);
4.111 + fputs("\n", stdout);
4.112 + }
4.113 + }
4.114 + while (nread);
4.115 }
4.116
4.117 - if (err)
4.118 - printf("Reading termination condition: %s\n", l4sys_errtostr(err));
4.119 -
4.120 printf("Data shown.\n");
4.121
4.122 return 0;