# HG changeset patch # User Paul Boddie # Date 1629566793 -7200 # Node ID dea9c3ee5f60ea10ffd2c63817fa746975ed12b2 # Parent a354a465462b116a35227a6db3386477806107d8 Introduced blocking operations as the default for files and pipes. diff -r a354a465462b -r dea9c3ee5f60 docs/wiki/Files --- a/docs/wiki/Files Tue Aug 17 23:44:36 2021 +0200 +++ b/docs/wiki/Files Sat Aug 21 19:26:33 2021 +0200 @@ -189,7 +189,7 @@ Pipes are opened using a special function: {{{ -long client_pipe(file_t **reader, file_t **writer); +long client_pipe(file_t **reader, file_t **writer, flags_t flags); }}} Each pipe endpoint may be closed using `client_close`. diff -r a354a465462b -r dea9c3ee5f60 libfsclient/include/fsclient/client.h --- a/libfsclient/include/fsclient/client.h Tue Aug 17 23:44:36 2021 +0200 +++ b/libfsclient/include/fsclient/client.h Sat Aug 21 19:26:33 2021 +0200 @@ -42,8 +42,8 @@ file_t *client_opendir(const char *name); file_t *client_opendir_using(const char *name, l4_cap_idx_t server); -long client_pipe(file_t **reader, file_t **writer); -long client_pipe_using(file_t **reader, file_t **writer, l4_cap_idx_t server); +long client_pipe(file_t **reader, file_t **writer, flags_t flags); +long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server); /* File and region operations. */ diff -r a354a465462b -r dea9c3ee5f60 libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/libfsclient/lib/src/client.cc Sat Aug 21 19:26:33 2021 +0200 @@ -272,14 +272,14 @@ /* Open a pipe object. */ -long client_pipe(file_t **reader, file_t **writer) +long client_pipe(file_t **reader, file_t **writer, flags_t flags) { l4_cap_idx_t server = l4re_env_get_cap("pipes"); - return client_pipe_using(reader, writer, server); + return client_pipe_using(reader, writer, flags, server); } -long client_pipe_using(file_t **reader, file_t **writer, l4_cap_idx_t server) +long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server) { if (l4_is_invalid_cap(server)) return -L4_EINVAL; @@ -299,6 +299,15 @@ long err = pipe_open(DEFAULT_PIPE_SIZE, *reader, *writer, server); + /* Set blocking if successful and non-blocking is not indicated. */ + + if (!err && !(flags & O_NONBLOCK)) + { + err = client_set_blocking(*reader, NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED); + if (!err) + err = client_set_blocking(*writer, NOTIFY_SPACE_AVAILABLE | NOTIFY_PEER_CLOSED); + } + if (err) { free(*reader); diff -r a354a465462b -r dea9c3ee5f60 libfsclient/lib/src/file.cc --- a/libfsclient/lib/src/file.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/libfsclient/lib/src/file.cc Sat Aug 21 19:26:33 2021 +0200 @@ -98,9 +98,11 @@ ipc_cap_free_um(file->ref); /* Only unsubscribe after actually closing the file and sending any - notifications. */ + notifications. This depends on a valid reference, so it is also tested + here. */ - get_task_notifier()->unsubscribe(file); + if (l4_is_valid_cap(file->ref)) + get_task_notifier()->unsubscribe(file); if (file->memory != NULL) ipc_detach_dataspace(file->memory); @@ -183,6 +185,9 @@ long file_flush(file_t *file) { + if (l4_is_invalid_cap(file->ref)) + return -L4_EINVAL; + client_Flush _file(file->ref); long err = _file.flush(file->data_current, &file->size); diff -r a354a465462b -r dea9c3ee5f60 libfsserver/lib/files/ext2_file_opener.cc --- a/libfsserver/lib/files/ext2_file_opener.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sat Aug 21 19:26:33 2021 +0200 @@ -79,16 +79,6 @@ static void _read_directory(Ext2FileOpener *opener, fileid_t fileid, file_t *writer) { - /* Subscribe to space and closure notifications on the pipe. */ - - long err = client_set_blocking(writer, NOTIFY_SPACE_AVAILABLE | NOTIFY_PEER_CLOSED); - - if (err) - { - client_close(writer); - return; - } - opener->read_directory(fileid, writer); client_close(writer); @@ -131,7 +121,7 @@ // NOTE: Might be more appropriate to use lower-level file operations to // NOTE: avoid unnecessary mapping of the reader's memory region. - long err = client_pipe(&reader, &writer); + long err = client_pipe(&reader, &writer, 0); if (err) return err; @@ -148,7 +138,7 @@ /* Discard the reader structure but preserve the capability. */ reader->ref = L4_INVALID_CAP; - file_close(reader); + client_close(reader); /* Return an indication that the capability will be propagated and not retained. This is explicitly supported by the opener context. */ diff -r a354a465462b -r dea9c3ee5f60 libfsserver/lib/files/host_file_opener.cc --- a/libfsserver/lib/files/host_file_opener.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/libfsserver/lib/files/host_file_opener.cc Sat Aug 21 19:26:33 2021 +0200 @@ -25,6 +25,7 @@ #include #include +#include #include "host_file_accessor.h" #include "host_file_opener.h" @@ -104,7 +105,7 @@ // NOTE: Might be more appropriate to use lower-level file operations to // NOTE: avoid unnecessary mapping of the reader's memory region. - long err = client_pipe(&reader, &writer); + long err = client_pipe(&reader, &writer, O_NONBLOCK); if (err) return err; diff -r a354a465462b -r dea9c3ee5f60 libfsserver/lib/pipes/pipe_paging.cc --- a/libfsserver/lib/pipes/pipe_paging.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/libfsserver/lib/pipes/pipe_paging.cc Sat Aug 21 19:26:33 2021 +0200 @@ -24,8 +24,6 @@ #include "page_queue_partitioned.h" #include "pipe_paging.h" -#include "notifier_client.h" - PipePaging::PipePaging(Memory *memory, offset_t size) diff -r a354a465462b -r dea9c3ee5f60 tests/dstest_file_readdir.cc --- a/tests/dstest_file_readdir.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/tests/dstest_file_readdir.cc Sat Aug 21 19:26:33 2021 +0200 @@ -68,6 +68,9 @@ char *filename = argv[1]; bool have_uid = (argc > 2) && strlen(argv[2]); sys_uid_t uid = have_uid ? atoi(argv[2]) : 0; + + printf("Opening %s...\n", filename); + file_t *file = open_directory(filename, have_uid, uid); if (file == NULL) @@ -76,6 +79,8 @@ return 1; } + printf("Reading...\n"); + struct dirent *dirent; while ((dirent = client_readdir(file)) != NULL) diff -r a354a465462b -r dea9c3ee5f60 tests/dstest_pipe_client.cc --- a/tests/dstest_pipe_client.cc Tue Aug 17 23:44:36 2021 +0200 +++ b/tests/dstest_pipe_client.cc Sat Aug 21 19:26:33 2021 +0200 @@ -30,6 +30,7 @@ #include /* sleep */ #include +#include @@ -148,10 +149,11 @@ int main(void) { - /* Invoke the open method to receive the pipe endpoint references. */ + /* Obtain pipe endpoint references. Blocking will be set up manually. */ file_t *reader1, *reader2, *writer1, *writer2; - long err = client_pipe(&reader1, &writer1) || client_pipe(&reader2, &writer2); + long err = client_pipe(&reader1, &writer1, O_NONBLOCK) || + client_pipe(&reader2, &writer2, O_NONBLOCK); if (err) {