1.1 --- a/include/fsclient/client.h Tue May 05 22:42:13 2020 +0200
1.2 +++ b/include/fsclient/client.h Sun Jul 26 23:16:06 2020 +0200
1.3 @@ -79,4 +79,13 @@
1.4
1.5 ssize_t client_write(file_descriptor_t *desc, const void *buf, size_t count);
1.6
1.7 +/* Pipe opening. */
1.8 +
1.9 +long client_pipe(file_descriptor_t *reader, file_descriptor_t *writer);
1.10 +
1.11 +/* Pipe access. */
1.12 +
1.13 +void *client_current_region(file_descriptor_t *desc);
1.14 +void *client_next_region(file_descriptor_t *desc);
1.15 +
1.16 EXTERN_C_END
2.1 --- a/include/fsclient/fsdesc.h Tue May 05 22:42:13 2020 +0200
2.2 +++ b/include/fsclient/fsdesc.h Sun Jul 26 23:16:06 2020 +0200
2.3 @@ -46,7 +46,8 @@
2.4
2.5 size_t start_pos; /* start position of the mapped dataspace in the file */
2.6 size_t end_pos; /* end position of the mapped dataspace in the file */
2.7 - size_t size; /* file size (used by the client for seek) */
2.8 + size_t size; /* file size (used by the client for seek) or
2.9 + region size (for pipes, identical to buffer.size) */
2.10
2.11 /* Shared buffer communication. */
2.12
2.13 @@ -81,6 +82,11 @@
2.14 size_t data_start; /* offset of available data */
2.15 size_t data_end; /* offset of the end of available data */
2.16
2.17 + /* File/pipe indicator. */
2.18 +
2.19 + int can_mmap; /* indicates whether mmap can be used instead of region
2.20 + navigation */
2.21 +
2.22 } file_descriptor_t;
2.23
2.24 /* Allocation operations. */
3.1 --- a/include/fsclient/fsdesc_client.h Tue May 05 22:42:13 2020 +0200
3.2 +++ b/include/fsclient/fsdesc_client.h Sun Jul 26 23:16:06 2020 +0200
3.3 @@ -49,4 +49,13 @@
3.4 long fs_mmap(file_descriptor_t *desc, off_t position, size_t length);
3.5 long fs_yield(file_descriptor_t *desc);
3.6
3.7 +/* Pipe opener methods. */
3.8 +
3.9 +long fs_pipe(l4_cap_idx_t server, file_descriptor_t *reader, file_descriptor_t *writer);
3.10 +
3.11 +/* Pipe access methods. */
3.12 +
3.13 +long fs_current_region(file_descriptor_t *desc);
3.14 +long fs_next_region(file_descriptor_t *desc);
3.15 +
3.16 EXTERN_C_END
4.1 --- a/lib/src/Makefile Tue May 05 22:42:13 2020 +0200
4.2 +++ b/lib/src/Makefile Sun Jul 26 23:16:06 2020 +0200
4.3 @@ -21,7 +21,7 @@
4.4
4.5 CLIENT_INTERFACES_C = \
4.6 file filesystem mapped_file \
4.7 - opener opener_context sync \
4.8 + opener opener_context pipe pipe_opener sync
4.9
4.10 # Generated and plain source files.
4.11
5.1 --- a/lib/src/client.c Tue May 05 22:42:13 2020 +0200
5.2 +++ b/lib/src/client.c Sun Jul 26 23:16:06 2020 +0200
5.3 @@ -207,6 +207,10 @@
5.4 desc->obj.buffer.addr = client_mmap(desc, 0, buffer_size ? buffer_size
5.5 : DEFAULT_BUFFER_SIZE);
5.6
5.7 + /* Files can always be mapped using mmap. */
5.8 +
5.9 + desc->can_mmap = 1;
5.10 +
5.11 /* Return with success if a buffer was assigned. */
5.12
5.13 if (desc->obj.buffer.addr)
5.14 @@ -220,6 +224,38 @@
5.15
5.16
5.17
5.18 +/* Open a pipe object. */
5.19 +
5.20 +long client_pipe(file_descriptor_t *reader, file_descriptor_t *writer)
5.21 +{
5.22 + long err;
5.23 +
5.24 + if ((reader == NULL) || (writer == NULL))
5.25 + return -L4_EINVAL;
5.26 +
5.27 + if (fsdesc_init_cap(reader, "pipes") == NULL)
5.28 + return -L4_ENOMEM;
5.29 +
5.30 + if (fsdesc_init_cap(writer, "pipes") == NULL)
5.31 + return -L4_ENOMEM;
5.32 +
5.33 + err = fs_pipe(reader->server, reader, writer);
5.34 + if (err)
5.35 + return err;
5.36 +
5.37 + if ((client_current_region(writer) == NULL) ||
5.38 + (client_current_region(reader) == NULL))
5.39 + {
5.40 + client_close(reader);
5.41 + client_close(writer);
5.42 + return -L4_ENOMEM;
5.43 + }
5.44 +
5.45 + return L4_EOK;
5.46 +}
5.47 +
5.48 +
5.49 +
5.50 /* Start synchronisation with the object. */
5.51
5.52 long client_begin(file_descriptor_t *desc)
5.53 @@ -256,24 +292,37 @@
5.54
5.55 static long _flush(file_descriptor_t *desc, size_t position)
5.56 {
5.57 + long err;
5.58 +
5.59 /* Where the position is outside the current region, re-map. */
5.60
5.61 - if ((position < desc->obj.start_pos) || (position >= desc->obj.start_pos + desc->obj.buffer.size))
5.62 + if ((position < desc->obj.start_pos) ||
5.63 + (position >= desc->obj.start_pos + desc->obj.buffer.size))
5.64 {
5.65 - if (!client_mmap(desc, position, position + desc->obj.buffer.size))
5.66 - return -L4_EIO;
5.67 + if (desc->can_mmap)
5.68 + {
5.69 + if (!client_mmap(desc, position, position + desc->obj.buffer.size))
5.70 + return -L4_EIO;
5.71 + }
5.72 +
5.73 + /* Strict conditions for region navigation in pipes. */
5.74 +
5.75 + else if ((position != desc->obj.start_pos + desc->obj.buffer.size) ||
5.76 + (client_next_region(desc) == NULL))
5.77 + return -L4_EIO;
5.78 }
5.79
5.80 /* Otherwise, flush any written data in the current region. */
5.81
5.82 - else if (desc->written)
5.83 + else
5.84 {
5.85 - fs_flush(desc);
5.86 + err = fs_flush(desc);
5.87 + if (err)
5.88 + return err;
5.89 +
5.90 desc->written = 0;
5.91 }
5.92
5.93 - /* NOTE: Should return errors from the operations. */
5.94 -
5.95 return L4_EOK;
5.96 }
5.97
5.98 @@ -285,15 +334,12 @@
5.99 {
5.100 /* Flush and retain most buffer settings. */
5.101
5.102 - if (desc->written)
5.103 - {
5.104 - fs_flush(desc);
5.105 + long err = fs_flush(desc);
5.106 +
5.107 + if (!err)
5.108 desc->written = 0;
5.109 - }
5.110
5.111 - /* NOTE: Should return errors from the operations. */
5.112 -
5.113 - return L4_EOK;
5.114 + return err;
5.115 }
5.116
5.117
5.118 @@ -312,6 +358,21 @@
5.119
5.120
5.121
5.122 +/* Attach a file-like resource as a dataspace. */
5.123 +
5.124 +static void *_attach_region(file_descriptor_t *desc)
5.125 +{
5.126 + if (desc->obj.buffer.addr)
5.127 + ipc_detach_dataspace(desc->obj.buffer.addr);
5.128 +
5.129 + ipc_attach_dataspace(desc->ref, desc->obj.buffer.size,
5.130 + (void **) &desc->obj.buffer.addr);
5.131 +
5.132 + return desc->obj.buffer.addr;
5.133 +}
5.134 +
5.135 +
5.136 +
5.137 /* Map a memory region to a file. */
5.138
5.139 void *client_mmap(file_descriptor_t *desc, off_t position, size_t length)
5.140 @@ -319,15 +380,31 @@
5.141 if (fs_mmap(desc, position, length))
5.142 return NULL;
5.143
5.144 - /* Attach the filesystem object as a dataspace. */
5.145 + return _attach_region(desc);
5.146 +}
5.147 +
5.148 +
5.149
5.150 - if (desc->obj.buffer.addr)
5.151 - ipc_detach_dataspace(desc->obj.buffer.addr);
5.152 +/* Obtain the current region of a pipe. */
5.153 +
5.154 +void *client_current_region(file_descriptor_t *desc)
5.155 +{
5.156 + if (fs_current_region(desc))
5.157 + return NULL;
5.158
5.159 - ipc_attach_dataspace(desc->ref, desc->obj.buffer.size,
5.160 - (void **) &desc->obj.buffer.addr);
5.161 + return _attach_region(desc);
5.162 +}
5.163 +
5.164 +
5.165 +
5.166 +/* Obtain the next region of a pipe. */
5.167
5.168 - return desc->obj.buffer.addr;
5.169 +void *client_next_region(file_descriptor_t *desc)
5.170 +{
5.171 + if (fs_next_region(desc))
5.172 + return NULL;
5.173 +
5.174 + return _attach_region(desc);
5.175 }
5.176
5.177
6.1 --- a/lib/src/fsdesc.c Tue May 05 22:42:13 2020 +0200
6.2 +++ b/lib/src/fsdesc.c Sun Jul 26 23:16:06 2020 +0200
6.3 @@ -50,6 +50,11 @@
6.4 if (l4_is_invalid_cap(desc->server))
6.5 return NULL;
6.6
6.7 + /* Indicate an absent memory region. */
6.8 +
6.9 + desc->obj.buffer.addr = 0;
6.10 + desc->obj.buffer.size = 0;
6.11 +
6.12 /* Initialise state independently of the server. */
6.13
6.14 fsdesc_reset_buffer(desc, 0);
6.15 @@ -96,6 +101,8 @@
6.16 desc->data_start = 0;
6.17 desc->data_end = 0;
6.18 desc->written = 0;
6.19 + desc->can_mmap = 0;
6.20 + desc->obj.size = 0;
6.21 desc->obj.start_pos = position;
6.22 }
6.23
7.1 --- a/lib/src/fsdesc_client.c Tue May 05 22:42:13 2020 +0200
7.2 +++ b/lib/src/fsdesc_client.c Sun Jul 26 23:16:06 2020 +0200
7.3 @@ -28,6 +28,8 @@
7.4 #include "mapped_file_client.h"
7.5 #include "opener_client.h"
7.6 #include "opener_context_client.h"
7.7 +#include "pipe_client.h"
7.8 +#include "pipe_opener_client.h"
7.9 #include "sync_client.h"
7.10
7.11 #include "fsdesc.h"
7.12 @@ -46,7 +48,9 @@
7.13 return Filesystem_getuserfs((ref_Filesystem) server, user.uid, user.gid, user.umask, ref);
7.14 }
7.15
7.16 -/* Filesystem access methods. */
7.17 +
7.18 +
7.19 +/* Filesystem context access methods. */
7.20
7.21 long
7.22 fs_context(file_descriptor_t *desc)
7.23 @@ -82,6 +86,8 @@
7.24 &desc->obj.size, &desc->ref);
7.25 }
7.26
7.27 +
7.28 +
7.29 /* Filesystem object access methods. */
7.30
7.31 long
7.32 @@ -121,7 +127,15 @@
7.33 long
7.34 fs_flush(file_descriptor_t *desc)
7.35 {
7.36 - return File_flush((ref_File) desc->ref, desc->data_start, &desc->obj.size);
7.37 + long err = File_flush((ref_File) desc->ref, desc->data_start, &desc->obj.size);
7.38 + if (err)
7.39 + return err;
7.40 +
7.41 + /* Update state from the server. */
7.42 +
7.43 + fs_update_from_size(desc);
7.44 +
7.45 + return L4_EOK;
7.46 }
7.47
7.48 long
7.49 @@ -212,3 +226,45 @@
7.50
7.51 return L4_EOK;
7.52 }
7.53 +
7.54 +
7.55 +
7.56 +/* Pipe access methods. */
7.57 +
7.58 +long
7.59 +fs_pipe(l4_cap_idx_t opener, file_descriptor_t *reader, file_descriptor_t *writer)
7.60 +{
7.61 + long err = PipeOpener_pipe((ref_PipeOpener) opener, &reader->ref, &writer->ref);
7.62 + if (err)
7.63 + return err;
7.64 +
7.65 + err = fs_current_region(reader);
7.66 + if (err)
7.67 + return err;
7.68 +
7.69 + return fs_current_region(writer);
7.70 +}
7.71 +
7.72 +
7.73 +
7.74 +/* Pipe access methods. */
7.75 +
7.76 +long
7.77 +fs_current_region(file_descriptor_t *desc)
7.78 +{
7.79 + /* Reset the data extents in the region, updated by flushing. */
7.80 +
7.81 + fsdesc_reset_buffer(desc, 0);
7.82 +
7.83 + return Pipe_current_region((ref_Pipe) desc->ref, &desc->obj.buffer.size);
7.84 +}
7.85 +
7.86 +long
7.87 +fs_next_region(file_descriptor_t *desc)
7.88 +{
7.89 + /* Reset the data extents in the region, updated by flushing. */
7.90 +
7.91 + fsdesc_reset_buffer(desc, 0);
7.92 +
7.93 + return Pipe_next_region((ref_Pipe) desc->ref, &desc->obj.buffer.size, &desc->data_end);
7.94 +}