1.1 --- a/docs/wiki/Files Tue Aug 17 23:44:36 2021 +0200
1.2 +++ b/docs/wiki/Files Sat Aug 21 19:26:33 2021 +0200
1.3 @@ -189,7 +189,7 @@
1.4 Pipes are opened using a special function:
1.5
1.6 {{{
1.7 -long client_pipe(file_t **reader, file_t **writer);
1.8 +long client_pipe(file_t **reader, file_t **writer, flags_t flags);
1.9 }}}
1.10
1.11 Each pipe endpoint may be closed using `client_close`.
2.1 --- a/libfsclient/include/fsclient/client.h Tue Aug 17 23:44:36 2021 +0200
2.2 +++ b/libfsclient/include/fsclient/client.h Sat Aug 21 19:26:33 2021 +0200
2.3 @@ -42,8 +42,8 @@
2.4 file_t *client_opendir(const char *name);
2.5 file_t *client_opendir_using(const char *name, l4_cap_idx_t server);
2.6
2.7 -long client_pipe(file_t **reader, file_t **writer);
2.8 -long client_pipe_using(file_t **reader, file_t **writer, l4_cap_idx_t server);
2.9 +long client_pipe(file_t **reader, file_t **writer, flags_t flags);
2.10 +long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server);
2.11
2.12 /* File and region operations. */
2.13
3.1 --- a/libfsclient/lib/src/client.cc Tue Aug 17 23:44:36 2021 +0200
3.2 +++ b/libfsclient/lib/src/client.cc Sat Aug 21 19:26:33 2021 +0200
3.3 @@ -272,14 +272,14 @@
3.4
3.5 /* Open a pipe object. */
3.6
3.7 -long client_pipe(file_t **reader, file_t **writer)
3.8 +long client_pipe(file_t **reader, file_t **writer, flags_t flags)
3.9 {
3.10 l4_cap_idx_t server = l4re_env_get_cap("pipes");
3.11
3.12 - return client_pipe_using(reader, writer, server);
3.13 + return client_pipe_using(reader, writer, flags, server);
3.14 }
3.15
3.16 -long client_pipe_using(file_t **reader, file_t **writer, l4_cap_idx_t server)
3.17 +long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server)
3.18 {
3.19 if (l4_is_invalid_cap(server))
3.20 return -L4_EINVAL;
3.21 @@ -299,6 +299,15 @@
3.22
3.23 long err = pipe_open(DEFAULT_PIPE_SIZE, *reader, *writer, server);
3.24
3.25 + /* Set blocking if successful and non-blocking is not indicated. */
3.26 +
3.27 + if (!err && !(flags & O_NONBLOCK))
3.28 + {
3.29 + err = client_set_blocking(*reader, NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED);
3.30 + if (!err)
3.31 + err = client_set_blocking(*writer, NOTIFY_SPACE_AVAILABLE | NOTIFY_PEER_CLOSED);
3.32 + }
3.33 +
3.34 if (err)
3.35 {
3.36 free(*reader);
4.1 --- a/libfsclient/lib/src/file.cc Tue Aug 17 23:44:36 2021 +0200
4.2 +++ b/libfsclient/lib/src/file.cc Sat Aug 21 19:26:33 2021 +0200
4.3 @@ -98,9 +98,11 @@
4.4 ipc_cap_free_um(file->ref);
4.5
4.6 /* Only unsubscribe after actually closing the file and sending any
4.7 - notifications. */
4.8 + notifications. This depends on a valid reference, so it is also tested
4.9 + here. */
4.10
4.11 - get_task_notifier()->unsubscribe(file);
4.12 + if (l4_is_valid_cap(file->ref))
4.13 + get_task_notifier()->unsubscribe(file);
4.14
4.15 if (file->memory != NULL)
4.16 ipc_detach_dataspace(file->memory);
4.17 @@ -183,6 +185,9 @@
4.18
4.19 long file_flush(file_t *file)
4.20 {
4.21 + if (l4_is_invalid_cap(file->ref))
4.22 + return -L4_EINVAL;
4.23 +
4.24 client_Flush _file(file->ref);
4.25 long err = _file.flush(file->data_current, &file->size);
4.26
5.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Tue Aug 17 23:44:36 2021 +0200
5.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sat Aug 21 19:26:33 2021 +0200
5.3 @@ -79,16 +79,6 @@
5.4
5.5 static void _read_directory(Ext2FileOpener *opener, fileid_t fileid, file_t *writer)
5.6 {
5.7 - /* Subscribe to space and closure notifications on the pipe. */
5.8 -
5.9 - long err = client_set_blocking(writer, NOTIFY_SPACE_AVAILABLE | NOTIFY_PEER_CLOSED);
5.10 -
5.11 - if (err)
5.12 - {
5.13 - client_close(writer);
5.14 - return;
5.15 - }
5.16 -
5.17 opener->read_directory(fileid, writer);
5.18
5.19 client_close(writer);
5.20 @@ -131,7 +121,7 @@
5.21 // NOTE: Might be more appropriate to use lower-level file operations to
5.22 // NOTE: avoid unnecessary mapping of the reader's memory region.
5.23
5.24 - long err = client_pipe(&reader, &writer);
5.25 + long err = client_pipe(&reader, &writer, 0);
5.26
5.27 if (err)
5.28 return err;
5.29 @@ -148,7 +138,7 @@
5.30 /* Discard the reader structure but preserve the capability. */
5.31
5.32 reader->ref = L4_INVALID_CAP;
5.33 - file_close(reader);
5.34 + client_close(reader);
5.35
5.36 /* Return an indication that the capability will be propagated and not
5.37 retained. This is explicitly supported by the opener context. */
6.1 --- a/libfsserver/lib/files/host_file_opener.cc Tue Aug 17 23:44:36 2021 +0200
6.2 +++ b/libfsserver/lib/files/host_file_opener.cc Sat Aug 21 19:26:33 2021 +0200
6.3 @@ -25,6 +25,7 @@
6.4 #include <sys/stat.h>
6.5
6.6 #include <fsclient/client.h>
6.7 +#include <systypes/fcntl.h>
6.8
6.9 #include "host_file_accessor.h"
6.10 #include "host_file_opener.h"
6.11 @@ -104,7 +105,7 @@
6.12 // NOTE: Might be more appropriate to use lower-level file operations to
6.13 // NOTE: avoid unnecessary mapping of the reader's memory region.
6.14
6.15 - long err = client_pipe(&reader, &writer);
6.16 + long err = client_pipe(&reader, &writer, O_NONBLOCK);
6.17
6.18 if (err)
6.19 return err;
7.1 --- a/libfsserver/lib/pipes/pipe_paging.cc Tue Aug 17 23:44:36 2021 +0200
7.2 +++ b/libfsserver/lib/pipes/pipe_paging.cc Sat Aug 21 19:26:33 2021 +0200
7.3 @@ -24,8 +24,6 @@
7.4 #include "page_queue_partitioned.h"
7.5 #include "pipe_paging.h"
7.6
7.7 -#include "notifier_client.h"
7.8 -
7.9
7.10
7.11 PipePaging::PipePaging(Memory *memory, offset_t size)
8.1 --- a/tests/dstest_file_readdir.cc Tue Aug 17 23:44:36 2021 +0200
8.2 +++ b/tests/dstest_file_readdir.cc Sat Aug 21 19:26:33 2021 +0200
8.3 @@ -68,6 +68,9 @@
8.4 char *filename = argv[1];
8.5 bool have_uid = (argc > 2) && strlen(argv[2]);
8.6 sys_uid_t uid = have_uid ? atoi(argv[2]) : 0;
8.7 +
8.8 + printf("Opening %s...\n", filename);
8.9 +
8.10 file_t *file = open_directory(filename, have_uid, uid);
8.11
8.12 if (file == NULL)
8.13 @@ -76,6 +79,8 @@
8.14 return 1;
8.15 }
8.16
8.17 + printf("Reading...\n");
8.18 +
8.19 struct dirent *dirent;
8.20
8.21 while ((dirent = client_readdir(file)) != NULL)
9.1 --- a/tests/dstest_pipe_client.cc Tue Aug 17 23:44:36 2021 +0200
9.2 +++ b/tests/dstest_pipe_client.cc Sat Aug 21 19:26:33 2021 +0200
9.3 @@ -30,6 +30,7 @@
9.4 #include <unistd.h> /* sleep */
9.5
9.6 #include <fsclient/client.h>
9.7 +#include <systypes/fcntl.h>
9.8
9.9
9.10
9.11 @@ -148,10 +149,11 @@
9.12
9.13 int main(void)
9.14 {
9.15 - /* Invoke the open method to receive the pipe endpoint references. */
9.16 + /* Obtain pipe endpoint references. Blocking will be set up manually. */
9.17
9.18 file_t *reader1, *reader2, *writer1, *writer2;
9.19 - long err = client_pipe(&reader1, &writer1) || client_pipe(&reader2, &writer2);
9.20 + long err = client_pipe(&reader1, &writer1, O_NONBLOCK) ||
9.21 + client_pipe(&reader2, &writer2, O_NONBLOCK);
9.22
9.23 if (err)
9.24 {