1.1 --- a/docs/tools/make_docs.sh Fri Apr 07 17:47:06 2023 +0200
1.2 +++ b/docs/tools/make_docs.sh Sat Dec 09 22:13:54 2023 +0100
1.3 @@ -2,9 +2,8 @@
1.4
1.5 THISDIR=`dirname "$0"`
1.6 INDIR="$THISDIR/../wiki"
1.7 -OUTDIR="$THISDIR/../html"
1.8
1.9 -ROOT="Filesystems"
1.10 +ROOT="Departure"
1.11
1.12 MAPPING='--mapping WikiPedia https://en.wikipedia.org/wiki/'
1.13 THEME='--theme mercurial'
1.14 @@ -16,6 +15,13 @@
1.15 DOCINDEX='--document-index index.html'
1.16 fi
1.17
1.18 +if [ "$1" = '-o' ] ; then
1.19 + OUTDIR="$2"
1.20 + shift 2
1.21 +else
1.22 + OUTDIR="$THISDIR/../html"
1.23 +fi
1.24 +
1.25 FILENAMES=${*:-'--all'}
1.26
1.27 moinconvert --input-dir "$INDIR" \
2.1 --- a/docs/wiki/Client_Library Fri Apr 07 17:47:06 2023 +0200
2.2 +++ b/docs/wiki/Client_Library Sat Dec 09 22:13:54 2023 +0100
2.3 @@ -228,39 +228,39 @@
2.4 a given resource via a notifier object:
2.5
2.6 {{{
2.7 -long client_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier);
2.8 +long client_subscribe(file_t *file, notify_flags_t flags, notifier_t *notifier);
2.9 }}}
2.10
2.11 A notifier object can be common throughout all threads in a task, being
2.12 obtained using the following function:
2.13
2.14 {{{
2.15 -file_notifier_t *client_notifier_task();
2.16 +notifier_t *client_notifier_task();
2.17 }}}
2.18
2.19 Alternatively, a local notifier can be created for use within a thread:
2.20
2.21 {{{
2.22 -file_notifier_t *client_notifier_local();
2.23 +notifier_t *client_notifier_local();
2.24 }}}
2.25
2.26 Local notifiers must be closed when they are no longer needed:
2.27
2.28 {{{
2.29 -void client_notifier_close(file_notifier_t *notifier);
2.30 +void client_notifier_close(notifier_t *notifier);
2.31 }}}
2.32
2.33 When notifications are no longer needed, an unsubscribe operation can be
2.34 invoked:
2.35
2.36 {{{
2.37 -long client_unsubscribe(file_t *file, file_notifier_t *notifier);
2.38 +long client_unsubscribe(file_t *file, notifier_t *notifier);
2.39 }}}
2.40
2.41 ==== Example ====
2.42
2.43 {{{
2.44 -file_notifier_t *notifier = client_notifier_local();
2.45 +notifier_t *notifier = client_notifier_local();
2.46 file_t *directory = client_open(filename, O_DIRECTORY);
2.47
2.48 if (client_opened(directory))
3.1 --- a/docs/wiki/Departure Fri Apr 07 17:47:06 2023 +0200
3.2 +++ b/docs/wiki/Departure Sat Dec 09 22:13:54 2023 +0100
3.3 @@ -19,7 +19,7 @@
3.4
3.5 subgraph cluster_client {
3.6 color=none; style=filled; fillcolor="#ccffcc";
3.7 - label="Client library"; URL="../Client_Library";
3.8 + label="Client library"; URL="Client_Library";
3.9
3.10 notifications [label="Notifications"];
3.11 io [label="Input/Output"];
3.12 @@ -27,7 +27,7 @@
3.13
3.14 subgraph cluster_components {
3.15 color=none; style=filled; fillcolor="#ccccff";
3.16 - label="Components"; URL="../Components";
3.17 + label="Components"; URL="Components";
3.18
3.19 pipes [label="Pipes"];
3.20 openers [label="Openers"];
3.21 @@ -38,7 +38,7 @@
3.22
3.23 subgraph cluster_server {
3.24 color=none; style=filled; fillcolor="#ffcccc";
3.25 - label="Server library"; URL="../Server_Library";
3.26 + label="Server library"; URL="Server_Library";
3.27
3.28 resources [label="Resources"];
3.29 registries [label="Registries"];
4.1 --- a/docs/wiki/Filesystem_Access Fri Apr 07 17:47:06 2023 +0200
4.2 +++ b/docs/wiki/Filesystem_Access Sat Dec 09 22:13:54 2023 +0100
4.3 @@ -314,6 +314,16 @@
4.4 subgraph {
4.5 rank=same;
4.6
4.7 + NotifierResource1_note [shape=note,style=filled,fillcolor=gold,label="Created to\nreceive\nnotifications"];
4.8 + NotifierResource1 [label="NotifierResource"];
4.9 + NotifierResource2 [label="NotifierResource"];
4.10 +
4.11 + NotifierResource1_note -> NotifierResource1 -> NotifierResource2 [dir=none,style=dotted];
4.12 + }
4.13 +
4.14 + subgraph {
4.15 + rank=same;
4.16 +
4.17 Resource1 [label="Resource\n(Pager)"];
4.18 Resource2 [label="Resource\n(Pager)"];
4.19 }
4.20 @@ -321,11 +331,11 @@
4.21 subgraph {
4.22 rank=same;
4.23
4.24 - Notifier1_subscribe_note [shape=note,style=filled,fillcolor=gold,label="Propagated to\nprovider"];
4.25 - Notifier1_subscribe [label="Notifier"];
4.26 - Notifier2_subscribe [label="Notifier"];
4.27 + NotifierResource1_subscribe_note [shape=note,style=filled,fillcolor=gold,label="Propagated to\nprovider"];
4.28 + NotifierResource1_subscribe [label="NotifierResource"];
4.29 + NotifierResource2_subscribe [label="NotifierResource"];
4.30
4.31 - Notifier1_subscribe_note -> Notifier1_subscribe -> Notifier2_subscribe [dir=none,style=dotted];
4.32 + NotifierResource1_subscribe_note -> NotifierResource1_subscribe -> NotifierResource2_subscribe [dir=none,style=dotted];
4.33 }
4.34
4.35 subgraph {
4.36 @@ -339,17 +349,19 @@
4.37
4.38 /* Subscribing. */
4.39
4.40 - Client1 -> Notifier1 [dir=none];
4.41 - Notifier1 -> Resource1 [label="subscribe"];
4.42 + Client1 -> Notifier1 [label="subscribe"];
4.43 + Notifier1 -> NotifierResource1 [dir=none];
4.44 + NotifierResource1 -> Resource1 [label="subscribe"];
4.45
4.46 - Resource1 -> Notifier1_subscribe [dir=none];
4.47 - Notifier1_subscribe -> Provider [label="subscribe"];
4.48 + Resource1 -> NotifierResource1_subscribe [dir=none];
4.49 + NotifierResource1_subscribe -> Provider [label="subscribe"];
4.50
4.51 - Client2 -> Notifier2 [dir=none];
4.52 - Notifier2 -> Resource2 [label="subscribe"];
4.53 + Client2 -> Notifier2 [label="subscribe"];
4.54 + Notifier2 -> NotifierResource2 [dir=none];
4.55 + NotifierResource2 -> Resource2 [label="subscribe"];
4.56
4.57 - Resource2 -> Notifier2_subscribe [dir=none];
4.58 - Notifier2_subscribe -> Provider [label="subscribe"];
4.59 + Resource2 -> NotifierResource2_subscribe [dir=none];
4.60 + NotifierResource2_subscribe -> Provider [label="subscribe"];
4.61 }
4.62 }}}
4.63
4.64 @@ -368,40 +380,48 @@
4.65 rankdir=LR;
4.66
4.67 subgraph {
4.68 - rank=same;
4.69 + rank=min;
4.70 +
4.71 + Client2 [label="Client\nprogram"];
4.72 + Client1 [label="Client\nprogram"];
4.73 + }
4.74 +
4.75 + subgraph {
4.76 + rank=max;
4.77
4.78 - Client1 [label="Client\nprogram"];
4.79 - Client2 [label="Client\nprogram"];
4.80 + Provider_note [shape=note,style=filled,fillcolor=gold,label="Propagates\nnotifications"];
4.81 + Provider [label="Provider"];
4.82 +
4.83 + NotifierResource1 [label="NotifierResource"];
4.84 + NotifierResource1_note [shape=note,style=filled,fillcolor=gold,label="Receives\nnotifications"];
4.85 +
4.86 + Provider_note -> Provider [dir=none,style=dotted];
4.87 + Provider -> NotifierResource1 [dir=none,style=invis];
4.88 + NotifierResource1 -> NotifierResource1_note [dir=none,style=dotted];
4.89 }
4.90
4.91 subgraph {
4.92 rank=same;
4.93
4.94 - Notifier1_note [shape=note,style=filled,fillcolor=gold,label="Registered for\nnotifications"];
4.95 - Notifier1 [label="Notifier"];
4.96 -
4.97 + Resource2_note [shape=note,style=filled,fillcolor=gold,label="Generates\nnotification"];
4.98 Resource2 [label="Resource\n(Pager)"];
4.99 - Resource2_note [shape=note,style=filled,fillcolor=gold,label="Generates\nnotification"];
4.100
4.101 - Notifier1_note -> Notifier1 [dir=none,style=dotted];
4.102 - Resource2 -> Resource2_note [dir=none,style=dotted];
4.103 - }
4.104 + Notifier1 [label="Notifier"];
4.105 + Notifier1_note [shape=note,style=filled,fillcolor=gold,label="Created for\nnotifications"];
4.106
4.107 - subgraph {
4.108 - rank=same;
4.109 -
4.110 - Provider_note [shape=note,style=filled,fillcolor=gold,label="Propagates\nnotifications"];
4.111 - Provider [label="Provider"];
4.112 -
4.113 - Provider_note -> Provider [dir=none,style=dotted];
4.114 + Resource2_note -> Resource2 [dir=none,style=dotted];
4.115 + Notifier1 -> Notifier1_note [dir=none,style=dotted];
4.116 }
4.117
4.118 /* A notification scenario. */
4.119
4.120 + Client1 -> Notifier1 [label="wait"];
4.121 +
4.122 Client2 -> Resource2 [label="resize"];
4.123 Resource2 -> Provider [label="notify_others"];
4.124 - Provider -> Notifier1 [label="notify"];
4.125 - Client1 -> Notifier1 [label="wait"];
4.126 +
4.127 + Provider -> NotifierResource1 [label="notify"];
4.128 + NotifierResource1 -> Notifier1 [label="notify"];
4.129 }
4.130 }}}
4.131
5.1 --- a/docs/wiki/Program_Loading Fri Apr 07 17:47:06 2023 +0200
5.2 +++ b/docs/wiki/Program_Loading Sat Dec 09 22:13:54 2023 +0100
5.3 @@ -7,6 +7,54 @@
5.4 fault handler configured to provide program file content whenever a region of
5.5 the program payload is encountered that is not currently resident in memory.
5.6
5.7 +<<TableOfContents(2,3)>>
5.8 +
5.9 +== Program Initialisation ==
5.10 +
5.11 +To load and initialise a program, a new task must be created, defining a
5.12 +separate address space for the program and allowing it to operate
5.13 +independently of other programs. For a program to actually run, a thread of
5.14 +execution must be created so that the program's instructions can be read and
5.15 +processed. Once running, the program must be able to interact with the system
5.16 +environment and to have its memory resources made available to it upon demand.
5.17 +
5.18 +A number of elements must be prepared to be able to run a program, these being
5.19 +summarised below.
5.20 +
5.21 +=== Program Executable File ===
5.22 +
5.23 +The program executable file is obtained and the program metadata loaded,
5.24 +identifying the memory regions and entry point (the location of the first
5.25 +instruction).
5.26 +
5.27 +=== Task and Threads ===
5.28 +
5.29 +A new task is created to hold the program. For this new task, new threads are
5.30 +created to run and support the program. One thread will run the actual
5.31 +program, and another will be used as the region mapper to handle page fault
5.32 +conditions.
5.33 +
5.34 +=== Thread Resources ===
5.35 +
5.36 +Memory is allocated for the new program's threads, particularly the stack for
5.37 +each thread.
5.38 +
5.39 +Each stack is populated with program argument and environment information. Of
5.40 +particular importance are the capabilities to be made available to the threads
5.41 +since these permit interaction with the rest of the system.
5.42 +
5.43 +The capabilities to be used by the threads must be mapped into the new task.
5.44 +
5.45 +=== Thread Configuration ===
5.46 +
5.47 +To connect the main thread of the program to its region mapper, an IPC gate
5.48 +must be created. This is mapped to the new task where the region mapper will
5.49 +bind to it, using it to expose its interface.
5.50 +
5.51 +Thread properties such as pagers and exception handlers are defined for the
5.52 +threads, with the main thread employing the newly created IPC gate capability
5.53 +to delegate paging to the region mapper.
5.54 +
5.55 == Internal Page Fault Handlers ==
5.56
5.57 When satisfying page faults for a task, one approach involves situating the
5.58 @@ -86,8 +134,7 @@
5.59
5.60 == External Page Fault Handlers ==
5.61
5.62 -Another approach that may be used to support an internal page fault handler
5.63 -deployed in a task is to employ an external page fault handler in the creating
5.64 +Another approach is to employ an external page fault handler in the creating
5.65 task. When a page fault occurs, the external handler ensures that the
5.66 appropriate content has been brought into its own memory space. It then
5.67 returns a flexpage from the handler routine to resolve the fault.
5.68 @@ -168,6 +215,11 @@
5.69
5.70 ########
5.71
5.72 +This arrangement may be used to support a program deployed in a task. Since an
5.73 +internal page fault handler is just another kind of program, this external
5.74 +pager arrangement can be constrained to only supporting an internal page fault
5.75 +handler deployed in a task.
5.76 +
5.77 == Configuring Programs ==
5.78
5.79 To provide an internal page fault handler alongside an actual program to be
5.80 @@ -201,7 +253,7 @@
5.81 IPCGate_note -> IPCGate [dir=none,style=dotted];
5.82 }
5.83
5.84 - InitCaps [shape=record,label="<head> Initial capabilities | {<s> \"server\" |<c> capability }"];
5.85 + InitCaps [shape=record,label="<head> Initial capabilities | {<s> ENV_INTERNAL_PAGER_NAME |<c> capability }"];
5.86
5.87 subgraph {
5.88 rank=same;
5.89 @@ -234,3 +286,27 @@
5.90 }}}
5.91
5.92 ########
5.93 +
5.94 +The creating task performs the following operations:
5.95 +
5.96 + 1. Create an IPC gate for communication between the program and its pager.
5.97 +
5.98 + 1. Map the IPC gate into the created task to be accessible via a given
5.99 + capability slot.
5.100 +
5.101 + 1. Define the IPC gate in the pager's initial capabilities using a
5.102 + well-defined name, allowing the pager to look up the capability in its
5.103 + environment.
5.104 +
5.105 + 1. Start the pager which itself obtains the IPC gate capability and binds to
5.106 + it, making itself available as the pager for the program.
5.107 +
5.108 + 1. Set the pager of the program to the IPC gate as mapped within the task.
5.109 +
5.110 + 1. Start the program which is already configured to send page faults via the
5.111 + IPC gate to the pager.
5.112 +
5.113 +Upon starting, the program will encounter a page fault immediately, unless
5.114 +some additional work was done to map memory pages into the task in advance.
5.115 +The internal pager or page fault handler will attempt to resolve these faults
5.116 +as they occur, being contacted by the kernel on the program's behalf.
6.1 --- a/docs/wiki/Roadmap Fri Apr 07 17:47:06 2023 +0200
6.2 +++ b/docs/wiki/Roadmap Sat Dec 09 22:13:54 2023 +0100
6.3 @@ -24,11 +24,23 @@
6.4 implementation when the `main` function returns control to the C library. It
6.5 seems worthwhile adopting this approach for compatibility with L4Re.
6.6
6.7 +Currently, a process server is implemented, but more control over the
6.8 +configuration of individual processes is desirable. It should be possible to
6.9 +run programs that cannot access the filesystem from which they were loaded,
6.10 +instead accessing a different, user-supplied filesystem.
6.11 +
6.12 == Library Loading Support ==
6.13
6.14 Currently, the program loading functionality does not support dynamic
6.15 library loading.
6.16
6.17 +== Program Environment Support ==
6.18 +
6.19 +The program loading functionality does relatively little beyond the
6.20 +initialisation of an initial environment that can start a program. Work is
6.21 +needed to handle situations like the exhaustion of the program stack and to be
6.22 +able to extend the stack appropriately.
6.23 +
6.24 == Test Sequencing and Shell Functionality ==
6.25
6.26 Currently, testing attempts to validate the behaviour of various operations
6.27 @@ -51,6 +63,10 @@
6.28 on Newlib that employed the filesystem access framework. It seems likely that
6.29 a similar approach will be taken for this iteration as well.
6.30
6.31 +The C library should provide support for all the elements of the frameworks
6.32 +implemented in this project, and it should also provide usable threading
6.33 +mechanisms.
6.34 +
6.35 == Virtual Filesystems ==
6.36
6.37 The previous iteration of this work provided a virtual filesystem server that
7.1 --- a/libexec/include/exec/pager.h Fri Apr 07 17:47:06 2023 +0200
7.2 +++ b/libexec/include/exec/pager.h Sat Dec 09 22:13:54 2023 +0100
7.3 @@ -21,6 +21,8 @@
7.4
7.5 #pragma once
7.6
7.7 +#include <l4/sys/utcb.h>
7.8 +
7.9 #include <exec/memory_area.h>
7.10
7.11
8.1 --- a/libexec/lib/src/external_pager.cc Fri Apr 07 17:47:06 2023 +0200
8.2 +++ b/libexec/lib/src/external_pager.cc Sat Dec 09 22:13:54 2023 +0100
8.3 @@ -58,7 +58,9 @@
8.4
8.5 void ExternalPager::close()
8.6 {
8.7 +#if DEBUG
8.8 printf("External pager closing...\n");
8.9 +#endif
8.10
8.11 /* Remove pager regions to avoid unmapping them twice. */
8.12
8.13 @@ -215,7 +217,7 @@
8.14 return L4_EOK;
8.15 }
8.16
8.17 - printf("not mapped at %lx for pc %lx\n", addr, pc);
8.18 + printf("ExternalPager: not mapped at %lx for pc %lx\n", addr, pc);
8.19
8.20 return err;
8.21 }
8.22 @@ -275,6 +277,8 @@
8.23
8.24 long ExternalPager::signal(unsigned long sig, unsigned long val)
8.25 {
8.26 + (void) val;
8.27 +
8.28 /* Handle the termination event of the internal pager. */
8.29
8.30 if (sig == 0)
9.1 --- a/libexec/lib/src/internal_pager.cc Fri Apr 07 17:47:06 2023 +0200
9.2 +++ b/libexec/lib/src/internal_pager.cc Sat Dec 09 22:13:54 2023 +0100
9.3 @@ -59,7 +59,9 @@
9.4
9.5 void InternalPager::close()
9.6 {
9.7 +#if DEBUG
9.8 printf("Internal pager closing...\n");
9.9 +#endif
9.10 }
9.11
9.12
9.13 @@ -126,7 +128,7 @@
9.14 return err;
9.15 }
9.16
9.17 - printf("not mapped at %lx for pc %lx\n", addr, pc);
9.18 + printf("InternalPager: not mapped at %lx for pc %lx\n", addr, pc);
9.19
9.20 return err;
9.21 }
9.22 @@ -161,6 +163,8 @@
9.23 long InternalPager::detach(address_t addr, address_t size, map_flags_t flags,
9.24 address_t *start, address_t *rsize, l4_cap_idx_t *ds)
9.25 {
9.26 + (void) size; (void) flags;
9.27 +
9.28 /* Obtain the region supporting the given address.
9.29 NOTE: All regions within the given range should be detached. */
9.30
10.1 --- a/libexec/lib/src/memory_area.cc Fri Apr 07 17:47:06 2023 +0200
10.2 +++ b/libexec/lib/src/memory_area.cc Sat Dec 09 22:13:54 2023 +0100
10.3 @@ -20,6 +20,7 @@
10.4 */
10.5
10.6 #include <l4/re/c/rm.h>
10.7 +#include <l4/sys/err.h>
10.8
10.9 #include <mem/memory_utils.h>
10.10
11.1 --- a/libfsclient/include/fsclient/client.h Fri Apr 07 17:47:06 2023 +0200
11.2 +++ b/libfsclient/include/fsclient/client.h Sat Dec 09 22:13:54 2023 +0100
11.3 @@ -100,14 +100,15 @@
11.4
11.5 /* More advanced notification operations. */
11.6
11.7 -void client_notifier_close(file_notifier_t *notifier);
11.8 -file_notifier_t *client_notifier_local(void);
11.9 -file_notifier_t *client_notifier_task(void);
11.10 +void client_notifier_close(notifier_t *notifier);
11.11 +notifier_t *client_notifier_local(void);
11.12 +notifier_t *client_notifier_task(void);
11.13
11.14 -long client_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier);
11.15 -long client_unsubscribe(file_t *file, file_notifier_t *notifier);
11.16 -long client_wait_file(file_t *file, file_notifier_t *notifier);
11.17 -long client_wait_files(file_t **file, file_notifier_t *notifier);
11.18 +long client_subscribe(file_t *file, notify_flags_t flags, notifier_t *notifier);
11.19 +long client_unsubscribe(file_t *file, notifier_t *notifier);
11.20 +
11.21 +long client_wait_file(file_t *file, notifier_t *notifier);
11.22 +long client_wait_files(file_t **file, notifier_t *notifier);
11.23
11.24 EXTERN_C_END
11.25
12.1 --- a/libfsclient/include/fsclient/file.h Fri Apr 07 17:47:06 2023 +0200
12.2 +++ b/libfsclient/include/fsclient/file.h Sat Dec 09 22:13:54 2023 +0100
12.3 @@ -29,13 +29,7 @@
12.4 #include <systypes/base.h>
12.5 #include <systypes/user.h>
12.6
12.7 -
12.8 -
12.9 -/* C compatibility types (defined in the implementation). */
12.10 -
12.11 -struct file_notifier;
12.12 -
12.13 -typedef struct file_notifier file_notifier_t;
12.14 +#include <fsclient/notify.h>
12.15
12.16
12.17
12.18 @@ -49,6 +43,10 @@
12.19
12.20 l4_cap_idx_t ref;
12.21
12.22 + /* Notification structure. */
12.23 +
12.24 + notifiable_t notifiable;
12.25 +
12.26 /* Mapped memory accessing a file region. */
12.27
12.28 char *memory;
12.29 @@ -71,10 +69,6 @@
12.30
12.31 notify_flags_t can_block;
12.32
12.33 - /* Notification structure. */
12.34 -
12.35 - notifiable_t notifiable;
12.36 -
12.37 /* Flags indicated when opening the file. */
12.38
12.39 flags_t flags;
12.40 @@ -151,14 +145,8 @@
12.41 notifiable_t *file_notifiable(file_t *file);
12.42 notify_flags_t file_notifications(file_t *file);
12.43
12.44 -void file_notify_close(file_notifier_t *notifier);
12.45 -file_notifier_t *file_notify_local(void);
12.46 -file_notifier_t *file_notify_task(void);
12.47 -
12.48 -long file_notify_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier);
12.49 -long file_notify_unsubscribe(file_t *file, file_notifier_t *notifier);
12.50 -long file_notify_wait_file(file_t *file, file_notifier_t *notifier);
12.51 -long file_notify_wait_files(file_t **file, file_notifier_t *notifier);
12.52 +long file_notify_wait_file(file_t *file, notifier_t *notifier);
12.53 +long file_notify_wait_files(file_t **file, notifier_t *notifier);
12.54
12.55
12.56
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/libfsclient/include/fsclient/notify.h Sat Dec 09 22:13:54 2023 +0100
13.3 @@ -0,0 +1,55 @@
13.4 +/*
13.5 + * Notification-related functions and types.
13.6 + *
13.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
13.8 + *
13.9 + * This program is free software; you can redistribute it and/or
13.10 + * modify it under the terms of the GNU General Public License as
13.11 + * published by the Free Software Foundation; either version 2 of
13.12 + * the License, or (at your option) any later version.
13.13 + *
13.14 + * This program is distributed in the hope that it will be useful,
13.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.17 + * GNU General Public License for more details.
13.18 + *
13.19 + * You should have received a copy of the GNU General Public License
13.20 + * along with this program; if not, write to the Free Software
13.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
13.22 + * Boston, MA 02110-1301, USA
13.23 + */
13.24 +
13.25 +#pragma once
13.26 +
13.27 +#include <systypes/base.h>
13.28 +
13.29 +
13.30 +
13.31 +/* C compatibility types (defined in the implementation). */
13.32 +
13.33 +struct notifier;
13.34 +
13.35 +typedef struct notifier notifier_t;
13.36 +
13.37 +
13.38 +
13.39 +EXTERN_C_BEGIN
13.40 +
13.41 +notifiable_t *notify_notifiable(notifiable_base_t *notifiable);
13.42 +notify_flags_t notify_notifications(notifiable_base_t *notifiable);
13.43 +notify_values_t notify_notification_values(notifiable_base_t *notifiable);
13.44 +
13.45 +void notify_close(notifier_t *notifier);
13.46 +
13.47 +notifier_t *notify_get_local(void);
13.48 +notifier_t *notify_get_task(void);
13.49 +
13.50 +long notify_subscribe(notifiable_t *notifiable, notify_flags_t flags, notifier_t *notifier);
13.51 +long notify_unsubscribe(notifiable_t *notifiable, notifier_t *notifier);
13.52 +
13.53 +long notify_wait(notifiable_t *notifiable, notifier_t *notifier);
13.54 +long notify_wait_many(notifiable_t **notifiable, notifier_t *notifier);
13.55 +
13.56 +EXTERN_C_END
13.57 +
13.58 +// vim: tabstop=2 expandtab shiftwidth=2
14.1 --- a/libfsclient/include/fsclient/process.h Fri Apr 07 17:47:06 2023 +0200
14.2 +++ b/libfsclient/include/fsclient/process.h Sat Dec 09 22:13:54 2023 +0100
14.3 @@ -28,14 +28,6 @@
14.4
14.5
14.6
14.7 -/* C compatibility types (defined in the implementation). */
14.8 -
14.9 -struct process_notifier;
14.10 -
14.11 -typedef struct process_notifier process_notifier_t;
14.12 -
14.13 -
14.14 -
14.15 EXTERN_C_BEGIN
14.16
14.17 /* File access abstraction compatible with notifiable_base_t. */
14.18 @@ -59,21 +51,20 @@
14.19 process_t *process_new();
14.20 void process_close(process_t *process);
14.21 long process_error(process_t *process);
14.22 +void process_free(process_t *process);
14.23 void process_init(process_t *process);
14.24 +long process_spawn(int argc, const char *argv[], process_t **process);
14.25 long process_start(process_t *process, int argc, const char *argv[]);
14.26 +long process_wait(process_t *process, notify_flags_t *flags, notify_values_t *values);
14.27
14.28 /* Notification support. */
14.29
14.30 notifiable_t *process_notifiable(process_t *process);
14.31 notify_flags_t process_notifications(process_t *process);
14.32 notify_values_t process_notification_values(process_t *process);
14.33 -void process_notify_close(process_notifier_t *notifier);
14.34 -process_notifier_t *process_notify_local();
14.35 -process_notifier_t *process_notify_task();
14.36 -long process_notify_subscribe(process_t *process, notify_flags_t flags, process_notifier_t *notifier);
14.37 -long process_notify_unsubscribe(process_t *process, process_notifier_t *notifier);
14.38 -long process_notify_wait_process(process_t *process, process_notifier_t *notifier);
14.39 -long process_notify_wait_processes(process_t **process, process_notifier_t *notifier);
14.40 +
14.41 +long process_notify_wait_process(process_t *process, notifier_t *notifier);
14.42 +long process_notify_wait_processes(process_t **process, notifier_t *notifier);
14.43
14.44 EXTERN_C_END
14.45
15.1 --- a/libfsclient/lib/src/Makefile Fri Apr 07 17:47:06 2023 +0200
15.2 +++ b/libfsclient/lib/src/Makefile Sat Dec 09 22:13:54 2023 +0100
15.3 @@ -23,7 +23,7 @@
15.4
15.5 CLIENT_INTERFACES_SRC_CC = $(call interfaces_to_client_cc,$(CLIENT_INTERFACES_CC))
15.6
15.7 -PLAIN_SRC_CC = client.cc file.cc process.cc
15.8 +PLAIN_SRC_CC = client.cc file.cc notify.cc process.cc
15.9
15.10 # Normal definitions.
15.11
16.1 --- a/libfsclient/lib/src/client.cc Fri Apr 07 17:47:06 2023 +0200
16.2 +++ b/libfsclient/lib/src/client.cc Sat Dec 09 22:13:54 2023 +0100
16.3 @@ -557,23 +557,23 @@
16.4
16.5 /* Close a notifier object. */
16.6
16.7 -void client_notifier_close(file_notifier_t *notifier)
16.8 +void client_notifier_close(notifier_t *notifier)
16.9 {
16.10 - file_notify_close(notifier);
16.11 + notify_close(notifier);
16.12 }
16.13
16.14 /* Obtain a local notifier object. */
16.15
16.16 -file_notifier_t *client_notifier_local()
16.17 +notifier_t *client_notifier_local()
16.18 {
16.19 - return file_notify_local();
16.20 + return notify_get_local();
16.21 }
16.22
16.23 /* Obtain a task-wide notifier object. */
16.24
16.25 -file_notifier_t *client_notifier_task()
16.26 +notifier_t *client_notifier_task()
16.27 {
16.28 - return file_notify_task();
16.29 + return notify_get_task();
16.30 }
16.31
16.32
16.33 @@ -766,7 +766,7 @@
16.34 /* Since blocking access is used with specific file notifications, the
16.35 per-task notifier is used. */
16.36
16.37 - file_notifier_t *notifier = client_notifier_task();
16.38 + notifier_t *notifier = client_notifier_task();
16.39
16.40 if (flags)
16.41 err = client_subscribe(file, flags, notifier);
16.42 @@ -784,12 +784,12 @@
16.43
16.44 /* Subscribe from events concerning a file. */
16.45
16.46 -long client_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier)
16.47 +long client_subscribe(file_t *file, notify_flags_t flags, notifier_t *notifier)
16.48 {
16.49 if (!client_opened(file))
16.50 return -L4_EINVAL;
16.51
16.52 - return file_notify_subscribe(file, flags, notifier);
16.53 + return notify_subscribe(file_notifiable(file), flags, notifier);
16.54 }
16.55
16.56
16.57 @@ -808,19 +808,19 @@
16.58
16.59 /* Unsubscribe from events concerning a file. */
16.60
16.61 -long client_unsubscribe(file_t *file, file_notifier_t *notifier)
16.62 +long client_unsubscribe(file_t *file, notifier_t *notifier)
16.63 {
16.64 if (!client_opened(file))
16.65 return -L4_EINVAL;
16.66
16.67 - return file_notify_unsubscribe(file, notifier);
16.68 + return notify_unsubscribe(file_notifiable(file), notifier);
16.69 }
16.70
16.71
16.72
16.73 /* Wait for events involving a specific file. */
16.74
16.75 -long client_wait_file(file_t *file, file_notifier_t *notifier)
16.76 +long client_wait_file(file_t *file, notifier_t *notifier)
16.77 {
16.78 if (!client_opened(file))
16.79 return -L4_EINVAL;
16.80 @@ -831,7 +831,7 @@
16.81 /* Wait for events concerning files, referencing a file object if an event is
16.82 delivered. */
16.83
16.84 -long client_wait_files(file_t **file, file_notifier_t *notifier)
16.85 +long client_wait_files(file_t **file, notifier_t *notifier)
16.86 {
16.87 return file_notify_wait_files(file, notifier);
16.88 }
17.1 --- a/libfsclient/lib/src/file.cc Fri Apr 07 17:47:06 2023 +0200
17.2 +++ b/libfsclient/lib/src/file.cc Sat Dec 09 22:13:54 2023 +0100
17.3 @@ -611,96 +611,47 @@
17.4
17.5
17.6
17.7 -/* Opaque notifier type for file_notifier_t. */
17.8 -
17.9 -struct file_notifier
17.10 -{
17.11 - ObjectNotifier *obj;
17.12 -};
17.13 -
17.14 /* Conversion to the generic notification types. */
17.15
17.16 notifiable_t *file_notifiable(file_t *file)
17.17 {
17.18 - return &file->notifiable;
17.19 + return notify_notifiable((notifiable_base_t *) file);
17.20 }
17.21
17.22 /* Return the notification flags for a file. */
17.23
17.24 notify_flags_t file_notifications(file_t *file)
17.25 {
17.26 - return file->notifiable.notifications;
17.27 -}
17.28 -
17.29 -/* Close a notifier object. */
17.30 -
17.31 -void file_notify_close(file_notifier_t *notifier)
17.32 -{
17.33 - delete notifier->obj;
17.34 - delete notifier;
17.35 -}
17.36 -
17.37 -/* Obtain a local notifier object. */
17.38 -
17.39 -file_notifier_t *file_notify_local()
17.40 -{
17.41 - file_notifier_t *notifier = new file_notifier_t;
17.42 -
17.43 - notifier->obj = notifier_get_local_notifier();
17.44 - return notifier;
17.45 -}
17.46 -
17.47 -/* Obtain the task-wide notifier object. */
17.48 -
17.49 -file_notifier_t *file_notify_task()
17.50 -{
17.51 - file_notifier_t *notifier = new file_notifier_t;
17.52 -
17.53 - notifier->obj = notifier_get_task_notifier();
17.54 - return notifier;
17.55 -}
17.56 -
17.57 -/* Subscribe to notification events on a file. */
17.58 -
17.59 -long file_notify_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier)
17.60 -{
17.61 - return notifier->obj->subscribe(file_notifiable(file), flags);
17.62 -}
17.63 -
17.64 -/* Unsubscribe from notification events on a file. */
17.65 -
17.66 -long file_notify_unsubscribe(file_t *file, file_notifier_t *notifier)
17.67 -{
17.68 - return notifier->obj->unsubscribe(file_notifiable(file));
17.69 + return notify_notifications((notifiable_base_t *) file);
17.70 }
17.71
17.72 /* Wait for a notification event on a file. */
17.73
17.74 -long file_notify_wait_file(file_t *file, file_notifier_t *notifier)
17.75 +long file_notify_wait_file(file_t *file, notifier_t *notifier)
17.76 {
17.77 - long err = notifier->obj->wait_object(file_notifiable(file));
17.78 + long err = notify_wait(file_notifiable(file), notifier);
17.79
17.80 /* Unsubscribe if a closure notification has been received. */
17.81
17.82 - if (!err && (file->notifiable.notifications & NOTIFY_PEER_CLOSED))
17.83 - file_notify_unsubscribe(file, notifier);
17.84 + if (!err && (file_notifications(file) & NOTIFY_PEER_CLOSED))
17.85 + notify_unsubscribe(file_notifiable(file), notifier);
17.86
17.87 return err;
17.88 }
17.89
17.90 /* Wait for notification events on files. */
17.91
17.92 -long file_notify_wait_files(file_t **file, file_notifier_t *notifier)
17.93 +long file_notify_wait_files(file_t **file, notifier_t *notifier)
17.94 {
17.95 notifiable_t *notifiable;
17.96 - long err = notifier->obj->wait(¬ifiable);
17.97 + long err = notify_wait_many(¬ifiable, notifier);
17.98
17.99 *file = (file_t *) notifiable->base;
17.100
17.101 /* Unsubscribe if a closure notification has been received. */
17.102
17.103 - if (!err && ((*file)->notifiable.notifications & NOTIFY_PEER_CLOSED))
17.104 - file_notify_unsubscribe(*file, notifier);
17.105 + if (!err && (notifiable->notifications & NOTIFY_PEER_CLOSED))
17.106 + notify_unsubscribe(notifiable, notifier);
17.107
17.108 return err;
17.109 }
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/libfsclient/lib/src/notify.cc Sat Dec 09 22:13:54 2023 +0100
18.3 @@ -0,0 +1,112 @@
18.4 +/*
18.5 + * Notification-related functions.
18.6 + *
18.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
18.8 + *
18.9 + * This program is free software; you can redistribute it and/or
18.10 + * modify it under the terms of the GNU General Public License as
18.11 + * published by the Free Software Foundation; either version 2 of
18.12 + * the License, or (at your option) any later version.
18.13 + *
18.14 + * This program is distributed in the hope that it will be useful,
18.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.17 + * GNU General Public License for more details.
18.18 + *
18.19 + * You should have received a copy of the GNU General Public License
18.20 + * along with this program; if not, write to the Free Software
18.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18.22 + * Boston, MA 02110-1301, USA
18.23 + */
18.24 +
18.25 +#include <notifier/notifier.h>
18.26 +
18.27 +#include "notify.h"
18.28 +
18.29 +
18.30 +
18.31 +/* Opaque notifier type for notifier_t. */
18.32 +
18.33 +struct notifier
18.34 +{
18.35 + ObjectNotifier *obj;
18.36 +};
18.37 +
18.38 +/* Return the notifiable details from a compatible object. */
18.39 +
18.40 +notifiable_t *notify_notifiable(notifiable_base_t *notifiable)
18.41 +{
18.42 + return ¬ifiable->notifiable;
18.43 +}
18.44 +
18.45 +/* Return the notification flags for an object. */
18.46 +
18.47 +notify_flags_t notify_notifications(notifiable_base_t *notifiable)
18.48 +{
18.49 + return notifiable->notifiable.notifications;
18.50 +}
18.51 +
18.52 +/* Return the notification values for an object. */
18.53 +
18.54 +notify_values_t notify_notification_values(notifiable_base_t *notifiable)
18.55 +{
18.56 + return notifiable->notifiable.values;
18.57 +}
18.58 +
18.59 +/* Close a notifier object. */
18.60 +
18.61 +void notify_close(notifier_t *notifier)
18.62 +{
18.63 + delete notifier->obj;
18.64 + delete notifier;
18.65 +}
18.66 +
18.67 +/* Obtain a local notifier object. */
18.68 +
18.69 +notifier_t *notify_get_local()
18.70 +{
18.71 + notifier_t *notifier = new notifier_t;
18.72 +
18.73 + notifier->obj = notifier_get_local_notifier();
18.74 + return notifier;
18.75 +}
18.76 +
18.77 +/* Obtain the task-wide notifier object. */
18.78 +
18.79 +notifier_t *notify_get_task()
18.80 +{
18.81 + notifier_t *notifier = new notifier_t;
18.82 +
18.83 + notifier->obj = notifier_get_task_notifier();
18.84 + return notifier;
18.85 +}
18.86 +
18.87 +/* Subscribe to notification events. */
18.88 +
18.89 +long notify_subscribe(notifiable_t *notifiable, notify_flags_t flags, notifier_t *notifier)
18.90 +{
18.91 + return notifier->obj->subscribe(notifiable, flags);
18.92 +}
18.93 +
18.94 +/* Unsubscribe from notification events. */
18.95 +
18.96 +long notify_unsubscribe(notifiable_t *notifiable, notifier_t *notifier)
18.97 +{
18.98 + return notifier->obj->unsubscribe(notifiable);
18.99 +}
18.100 +
18.101 +/* Wait for a notification event on a single object. */
18.102 +
18.103 +long notify_wait(notifiable_t *notifiable, notifier_t *notifier)
18.104 +{
18.105 + return notifier->obj->wait_object(notifiable);
18.106 +}
18.107 +
18.108 +/* Wait for notification events on multiple objects. */
18.109 +
18.110 +long notify_wait_many(notifiable_t **notifiable, notifier_t *notifier)
18.111 +{
18.112 + return notifier->obj->wait(notifiable);
18.113 +}
18.114 +
18.115 +// vim: tabstop=2 expandtab shiftwidth=2
19.1 --- a/libfsclient/lib/src/process.cc Fri Apr 07 17:47:06 2023 +0200
19.2 +++ b/libfsclient/lib/src/process.cc Sat Dec 09 22:13:54 2023 +0100
19.3 @@ -36,11 +36,11 @@
19.4
19.5 /* Utility functions. */
19.6
19.7 -static bool _process_terminated(process_t *process)
19.8 +static bool _process_terminated(notifiable_t *notifiable)
19.9 {
19.10 - return ((process->notifiable.notifications & NOTIFY_TASK_SIGNAL) &&
19.11 - (process->notifiable.values.sig == 0)) ||
19.12 - (process->notifiable.notifications & NOTIFY_TASK_ERROR);
19.13 + return ((notifiable->notifications & NOTIFY_TASK_SIGNAL) &&
19.14 + (notifiable->values.sig == 0)) ||
19.15 + (notifiable->notifications & NOTIFY_TASK_ERROR);
19.16 }
19.17
19.18
19.19 @@ -81,6 +81,20 @@
19.20 return L4_EOK;
19.21 }
19.22
19.23 +/* Discard and free the given process, similar to process_close but freeing the
19.24 + structure instead of reinitialising it. */
19.25 +
19.26 +void process_free(process_t *process)
19.27 +{
19.28 + if (process == NULL)
19.29 + return;
19.30 +
19.31 + if (l4_is_valid_cap(process->ref))
19.32 + ipc_cap_free_um(process->ref);
19.33 +
19.34 + free(process);
19.35 +}
19.36 +
19.37 /* Initialise the given process structure. */
19.38
19.39 void process_init(process_t *process)
19.40 @@ -95,6 +109,20 @@
19.41 process->notifiable.handler = NULL;
19.42 }
19.43
19.44 +/* A convenience function for creating and starting a process. */
19.45 +
19.46 +long process_spawn(int argc, const char *argv[], process_t **process)
19.47 +{
19.48 + *process = process_new();
19.49 +
19.50 + /* Start the process with the given arguments. */
19.51 +
19.52 + if (*process != NULL)
19.53 + return process_start(*process, argc, argv);
19.54 + else
19.55 + return -L4_ENOMEM;
19.56 +}
19.57 +
19.58 /* Start a process using the given arguments.
19.59 NOTE: This does not yet obtain input/output pipes. */
19.60
19.61 @@ -144,108 +172,90 @@
19.62 return err;
19.63 }
19.64
19.65 +/* A convenience function for waiting for a started process. */
19.66 +
19.67 +long process_wait(process_t *process, notify_flags_t *flags, notify_values_t *values)
19.68 +{
19.69 + /* Obtain the common notifier. */
19.70 +
19.71 + notifier_t *notifier = notify_get_task();
19.72 +
19.73 + /* Subscribe to the process for notifications. */
19.74 +
19.75 + long err = notify_subscribe(process_notifiable(process), NOTIFY_TASK_ALL, notifier);
19.76 +
19.77 + if (err)
19.78 + return err;
19.79 +
19.80 + /* Wait for a signal from the process. */
19.81 +
19.82 + err = process_notify_wait_process(process, notifier);
19.83 +
19.84 + if (err)
19.85 + return err;
19.86 +
19.87 + /* Obtain the notification flags and values. */
19.88 +
19.89 + *flags = process_notifications(process);
19.90 + *values = process_notification_values(process);
19.91 +
19.92 + /* Obtain any error, closing the process. */
19.93 +
19.94 + err = process_error(process);
19.95 + process_free(process);
19.96 + return err;
19.97 +}
19.98
19.99
19.100 -/* NOTE: Much of the code below could be unified with the file-related
19.101 - notification code. */
19.102 -
19.103 -/* Opaque notifier type for process_notifier_t. */
19.104 -
19.105 -struct process_notifier
19.106 -{
19.107 - ObjectNotifier *obj;
19.108 -};
19.109
19.110 /* Conversion to the generic notification types. */
19.111
19.112 notifiable_t *process_notifiable(process_t *process)
19.113 {
19.114 - return &process->notifiable;
19.115 + return notify_notifiable((notifiable_base_t *) process);
19.116 }
19.117
19.118 /* Return the notification flags for a process. */
19.119
19.120 notify_flags_t process_notifications(process_t *process)
19.121 {
19.122 - return process->notifiable.notifications;
19.123 + return notify_notifications((notifiable_base_t *) process);
19.124 }
19.125
19.126 /* Return the notification values for a process. */
19.127
19.128 notify_values_t process_notification_values(process_t *process)
19.129 {
19.130 - return process->notifiable.values;
19.131 -}
19.132 -
19.133 -/* Close a notifier object. */
19.134 -
19.135 -void process_notify_close(process_notifier_t *notifier)
19.136 -{
19.137 - delete notifier->obj;
19.138 - delete notifier;
19.139 -}
19.140 -
19.141 -/* Obtain a local notifier object. */
19.142 -
19.143 -process_notifier_t *process_notify_local()
19.144 -{
19.145 - process_notifier_t *notifier = new process_notifier_t;
19.146 -
19.147 - notifier->obj = notifier_get_local_notifier();
19.148 - return notifier;
19.149 -}
19.150 -
19.151 -/* Obtain the task-wide notifier object. */
19.152 -
19.153 -process_notifier_t *process_notify_task()
19.154 -{
19.155 - process_notifier_t *notifier = new process_notifier_t;
19.156 -
19.157 - notifier->obj = notifier_get_task_notifier();
19.158 - return notifier;
19.159 -}
19.160 -
19.161 -/* Subscribe to notification events on a process. */
19.162 -
19.163 -long process_notify_subscribe(process_t *process, notify_flags_t flags, process_notifier_t *notifier)
19.164 -{
19.165 - return notifier->obj->subscribe(process_notifiable(process), flags);
19.166 -}
19.167 -
19.168 -/* Unsubscribe from notification events on a process. */
19.169 -
19.170 -long process_notify_unsubscribe(process_t *process, process_notifier_t *notifier)
19.171 -{
19.172 - return notifier->obj->unsubscribe(process_notifiable(process));
19.173 + return notify_notification_values((notifiable_base_t *) process);
19.174 }
19.175
19.176 /* Wait for a notification event on a process. */
19.177
19.178 -long process_notify_wait_process(process_t *process, process_notifier_t *notifier)
19.179 +long process_notify_wait_process(process_t *process, notifier_t *notifier)
19.180 {
19.181 - long err = notifier->obj->wait_object(process_notifiable(process));
19.182 + long err = notify_wait(process_notifiable(process), notifier);
19.183
19.184 /* Unsubscribe if a termination notification has been received. */
19.185
19.186 - if (!err && _process_terminated(process))
19.187 - process_notify_unsubscribe(process, notifier);
19.188 + if (!err && _process_terminated(process_notifiable(process)))
19.189 + notify_unsubscribe(process_notifiable(process), notifier);
19.190
19.191 return err;
19.192 }
19.193
19.194 /* Wait for notification events on processes. */
19.195
19.196 -long process_notify_wait_processes(process_t **process, process_notifier_t *notifier)
19.197 +long process_notify_wait_processes(process_t **process, notifier_t *notifier)
19.198 {
19.199 notifiable_t *notifiable;
19.200 - long err = notifier->obj->wait(¬ifiable);
19.201 + long err = notify_wait_many(¬ifiable, notifier);
19.202
19.203 *process = (process_t *) notifiable->base;
19.204
19.205 /* Unsubscribe if a termination notification has been received. */
19.206
19.207 - if (!err && _process_terminated(*process))
19.208 - process_notify_unsubscribe(*process, notifier);
19.209 + if (!err && _process_terminated(notifiable))
19.210 + notify_unsubscribe(notifiable, notifier);
19.211
19.212 return err;
19.213 }
20.1 --- a/libipc/Control Fri Apr 07 17:47:06 2023 +0200
20.2 +++ b/libipc/Control Sat Dec 09 22:13:54 2023 +0100
20.3 @@ -1,3 +1,3 @@
20.4 -requires: libc libsystypes
20.5 +requires: libc
20.6 provides: libipc
20.7 maintainer: paul@boddie.org.uk
21.1 --- a/libipc/include/ipc/factory.h Fri Apr 07 17:47:06 2023 +0200
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,45 +0,0 @@
21.4 -/*
21.5 - * Factory-related data types.
21.6 - *
21.7 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
21.8 - *
21.9 - * This program is free software; you can redistribute it and/or
21.10 - * modify it under the terms of the GNU General Public License as
21.11 - * published by the Free Software Foundation; either version 2 of
21.12 - * the License, or (at your option) any later version.
21.13 - *
21.14 - * This program is distributed in the hope that it will be useful,
21.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.17 - * GNU General Public License for more details.
21.18 - *
21.19 - * You should have received a copy of the GNU General Public License
21.20 - * along with this program; if not, write to the Free Software
21.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
21.22 - * Boston, MA 02110-1301, USA
21.23 - */
21.24 -
21.25 -#pragma once
21.26 -
21.27 -#include <l4/sys/types.h>
21.28 -
21.29 -#include <systypes/factory.h>
21.30 -
21.31 -
21.32 -
21.33 -EXTERN_C_BEGIN
21.34 -
21.35 -/* Supporting data types for factory invocations. */
21.36 -
21.37 -typedef unsigned long unsigned_long;
21.38 -
21.39 -ipc_varg_typedef(long, ipc_varg(long))
21.40 -ipc_varg_typedef(unsigned_long, ipc_varg(unsigned_long))
21.41 -
21.42 -#define ipc_varg_long(value) \
21.43 -ipc_varg_mword(ipc_varg(long), value)
21.44 -
21.45 -#define ipc_varg_unsigned_long(value) \
21.46 -ipc_varg_umword(ipc_varg(unsigned_long), value)
21.47 -
21.48 -EXTERN_C_END
22.1 --- a/libsystypes/idl/dataspace_factory.idl Fri Apr 07 17:47:06 2023 +0200
22.2 +++ b/libsystypes/idl/dataspace_factory.idl Sat Dec 09 22:13:54 2023 +0100
22.3 @@ -1,5 +1,5 @@
22.4 -#include <ipc/factory.h>
22.5 #include <l4/re/protocols.h> /* L4RE_PROTO_DATASPACE */
22.6 +#include <systypes/factory.h>
22.7
22.8 /* Dataspace operations exposed via the factory interface. This appears to
22.9 involve extra tag values which are incorporated into the provided values.*/
23.1 --- a/libsystypes/idl/filesystem_factory.idl Fri Apr 07 17:47:06 2023 +0200
23.2 +++ b/libsystypes/idl/filesystem_factory.idl Sat Dec 09 22:13:54 2023 +0100
23.3 @@ -1,4 +1,5 @@
23.4 #include <systypes/base.h> /* sys_uid_t, sys_gid_t, sys_mode_t */
23.5 +#include <systypes/factory.h>
23.6
23.7 /* Filesystem operations exposed via the factory interface. This appears to
23.8 involve extra tag values which are incorporated into the provided values. */
24.1 --- a/libsystypes/include/systypes/base.h Fri Apr 07 17:47:06 2023 +0200
24.2 +++ b/libsystypes/include/systypes/base.h Sat Dec 09 22:13:54 2023 +0100
24.3 @@ -22,8 +22,9 @@
24.4 #pragma once
24.5
24.6 #include <l4/sys/compiler.h>
24.7 +#include <l4/sys/types.h>
24.8
24.9 -#include <systypes/factory.h>
24.10 +
24.11
24.12 EXTERN_C_BEGIN
24.13
24.14 @@ -72,13 +73,13 @@
24.15
24.16 /* Notifiable object types. */
24.17
24.18 -typedef struct
24.19 -{
24.20 - l4_cap_idx_t ref;
24.21 +/* Forward reference. */
24.22 +
24.23 +typedef struct notifiable_base notifiable_base_t;
24.24
24.25 -} notifiable_base_t;
24.26 +/* Structure maintaining notification state for a specific object. */
24.27
24.28 -typedef struct
24.29 +typedef struct notifiable
24.30 {
24.31 notifiable_base_t *base; /* access to the specific object */
24.32 notify_flags_t notifications; /* essential notifications */
24.33 @@ -89,6 +90,16 @@
24.34
24.35 } notifiable_t;
24.36
24.37 +/* A base structure extended by notifiable object structures like files and
24.38 + processes. */
24.39 +
24.40 +typedef struct notifiable_base
24.41 +{
24.42 + l4_cap_idx_t ref;
24.43 + notifiable_t notifiable;
24.44 +
24.45 +} notifiable_base_t;
24.46 +
24.47 /* Filesystem object properties. */
24.48
24.49 typedef unsigned long object_flags_t;
24.50 @@ -140,21 +151,6 @@
24.51 #define systypes_to_sys_mode(mode) \
24.52 ((sys_mode_t) mode)
24.53
24.54 -/* Factory types for L4 factory interface invocations. */
24.55 -
24.56 -ipc_varg_typedef(sys_mode_t, ipc_varg_sys_mode_t)
24.57 -ipc_varg_typedef(sys_uid_t, ipc_varg_sys_uid_t)
24.58 -ipc_varg_typedef(sys_gid_t, ipc_varg_sys_gid_t)
24.59 -
24.60 -#define ipc_varg_sys_mode(value) \
24.61 -ipc_varg_umword(ipc_varg_sys_mode_t, value)
24.62 -
24.63 -#define ipc_varg_sys_uid(value) \
24.64 -ipc_varg_umword(ipc_varg_sys_uid_t, value)
24.65 -
24.66 -#define ipc_varg_sys_gid(value) \
24.67 -ipc_varg_umword(ipc_varg_sys_gid_t, value)
24.68 -
24.69 EXTERN_C_END
24.70
24.71 // vim: tabstop=2 expandtab shiftwidth=2
25.1 --- a/libsystypes/include/systypes/factory.h Fri Apr 07 17:47:06 2023 +0200
25.2 +++ b/libsystypes/include/systypes/factory.h Sat Dec 09 22:13:54 2023 +0100
25.3 @@ -1,7 +1,7 @@
25.4 /*
25.5 * Factory-related data type macros.
25.6 *
25.7 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
25.8 + * Copyright (C) 2019, 2023 Paul Boddie <paul@boddie.org.uk>
25.9 *
25.10 * This program is free software; you can redistribute it and/or
25.11 * modify it under the terms of the GNU General Public License as
25.12 @@ -21,7 +21,7 @@
25.13
25.14 #pragma once
25.15
25.16 -#include <l4/sys/types.h>
25.17 +#include <systypes/base.h>
25.18
25.19
25.20
25.21 @@ -53,4 +53,36 @@
25.22
25.23 #define ipc_varg(type) ipc_varg_##type##_t
25.24
25.25 +
25.26 +
25.27 +/* Supporting data types for factory invocations. */
25.28 +
25.29 +typedef unsigned long unsigned_long;
25.30 +
25.31 +ipc_varg_typedef(long, ipc_varg(long))
25.32 +ipc_varg_typedef(unsigned_long, ipc_varg(unsigned_long))
25.33 +
25.34 +#define ipc_varg_long(value) \
25.35 +ipc_varg_mword(ipc_varg(long), value)
25.36 +
25.37 +#define ipc_varg_unsigned_long(value) \
25.38 +ipc_varg_umword(ipc_varg(unsigned_long), value)
25.39 +
25.40 +
25.41 +
25.42 +/* Additional, specific factory types for L4 factory interface invocations. */
25.43 +
25.44 +ipc_varg_typedef(sys_mode_t, ipc_varg_sys_mode_t)
25.45 +ipc_varg_typedef(sys_uid_t, ipc_varg_sys_uid_t)
25.46 +ipc_varg_typedef(sys_gid_t, ipc_varg_sys_gid_t)
25.47 +
25.48 +#define ipc_varg_sys_mode(value) \
25.49 +ipc_varg_umword(ipc_varg_sys_mode_t, value)
25.50 +
25.51 +#define ipc_varg_sys_uid(value) \
25.52 +ipc_varg_umword(ipc_varg_sys_uid_t, value)
25.53 +
25.54 +#define ipc_varg_sys_gid(value) \
25.55 +ipc_varg_umword(ipc_varg_sys_gid_t, value)
25.56 +
25.57 EXTERN_C_END
26.1 --- a/test_files/programs/clip.c Fri Apr 07 17:47:06 2023 +0200
26.2 +++ b/test_files/programs/clip.c Sat Dec 09 22:13:54 2023 +0100
26.3 @@ -156,7 +156,6 @@
26.4 fputs("\n\n", stdout);
26.5
26.6 client_close(file);
26.7 - client_notifier_close(client_notifier_task());
26.8
26.9 return 0;
26.10 }
27.1 --- a/tests/dstest_exec.cc Fri Apr 07 17:47:06 2023 +0200
27.2 +++ b/tests/dstest_exec.cc Sat Dec 09 22:13:54 2023 +0100
27.3 @@ -30,19 +30,11 @@
27.4
27.5 static long test_process(int argc, const char *argv[])
27.6 {
27.7 - /* Obtain the common notifier. */
27.8 -
27.9 - process_notifier_t *notifier = process_notify_task();
27.10 -
27.11 - /* Create a new process structure. */
27.12 -
27.13 - process_t process;
27.14 -
27.15 - process_init(&process);
27.16 + process_t *process;
27.17
27.18 /* Start the process. */
27.19
27.20 - long err = process_start(&process, argc, argv);
27.21 + long err = process_spawn(argc, argv, &process);
27.22
27.23 if (err)
27.24 {
27.25 @@ -52,19 +44,12 @@
27.26
27.27 printf("Finished program initiation.\n");
27.28
27.29 - /* Subscribe to the process for notifications. */
27.30 -
27.31 - err = process_notify_subscribe(&process, NOTIFY_TASK_ALL, notifier);
27.32 -
27.33 - if (err)
27.34 - {
27.35 - printf("Could not subscribe to process: %s\n", l4sys_errtostr(err));
27.36 - return err;
27.37 - }
27.38 -
27.39 /* Wait for a signal from the process. */
27.40
27.41 - err = process_notify_wait_process(&process, notifier);
27.42 + notify_flags_t flags;
27.43 + notify_values_t values;
27.44 +
27.45 + err = process_wait(process, &flags, &values);
27.46
27.47 if (err)
27.48 {
27.49 @@ -72,14 +57,8 @@
27.50 return err;
27.51 }
27.52
27.53 - notify_flags_t flags = process_notifications(&process);
27.54 - notify_values_t values = process_notification_values(&process);
27.55 -
27.56 printf("End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", flags, values.sig, values.val);
27.57 -
27.58 - err = process_error(&process);
27.59 - process_close(&process);
27.60 - return err;
27.61 + return L4_EOK;
27.62 }
27.63
27.64
27.65 @@ -96,7 +75,7 @@
27.66
27.67 /* Obtain the common notifier. */
27.68
27.69 - process_notifier_t *notifier = process_notify_task();
27.70 + notifier_t *notifier = notify_get_task();
27.71
27.72 /* Start a process for a non-existent program. */
27.73
27.74 @@ -123,7 +102,7 @@
27.75 if (err)
27.76 return 1;
27.77
27.78 - process_notify_close(notifier);
27.79 + notify_close(notifier);
27.80
27.81 printf("End of test.\n");
27.82 return 0;
28.1 --- a/tests/dstest_exec_many.cc Fri Apr 07 17:47:06 2023 +0200
28.2 +++ b/tests/dstest_exec_many.cc Sat Dec 09 22:13:54 2023 +0100
28.3 @@ -41,23 +41,15 @@
28.4
28.5 int num_processes = atoi(argv[1]);
28.6
28.7 - /* Obtain the common notifier. */
28.8 -
28.9 - process_notifier_t *notifier = process_notify_task();
28.10 -
28.11 - /* Create a new process structure. */
28.12 -
28.13 - process_t process;
28.14 -
28.15 - process_init(&process);
28.16 -
28.17 for (int i = 1; i <= num_processes; i++)
28.18 {
28.19 printf("[%d/%d] Start process...\n", i, num_processes);
28.20
28.21 /* Start a process for the given program. */
28.22
28.23 - err = process_start(&process, argc - 2, (const char **) argv + 2);
28.24 + process_t *process;
28.25 +
28.26 + err = process_spawn(argc - 2, (const char **) argv + 2, &process);
28.27
28.28 if (err)
28.29 {
28.30 @@ -67,19 +59,12 @@
28.31
28.32 printf("Finished program initiation.\n");
28.33
28.34 - /* Subscribe to the process for notifications. */
28.35 -
28.36 - err = process_notify_subscribe(&process, NOTIFY_TASK_ALL, notifier);
28.37 -
28.38 - if (err)
28.39 - {
28.40 - printf("Could not subscribe to process: %s\n", l4sys_errtostr(err));
28.41 - return 1;
28.42 - }
28.43 -
28.44 /* Wait for a signal from the process. */
28.45
28.46 - err = process_notify_wait_process(&process, notifier);
28.47 + notify_flags_t flags;
28.48 + notify_values_t values;
28.49 +
28.50 + err = process_wait(process, &flags, &values);
28.51
28.52 if (err)
28.53 {
28.54 @@ -87,16 +72,9 @@
28.55 return 1;
28.56 }
28.57
28.58 - notify_flags_t flags = process_notifications(&process);
28.59 - notify_values_t values = process_notification_values(&process);
28.60 -
28.61 printf("[%d/%d] End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", i, num_processes, flags, values.sig, values.val);
28.62 -
28.63 - process_close(&process);
28.64 }
28.65
28.66 - process_notify_close(notifier);
28.67 -
28.68 printf("End of test.\n");
28.69 return 0;
28.70 }
29.1 --- a/tests/dstest_pipe_client.cc Fri Apr 07 17:47:06 2023 +0200
29.2 +++ b/tests/dstest_pipe_client.cc Sat Dec 09 22:13:54 2023 +0100
29.3 @@ -89,7 +89,7 @@
29.4
29.5 /* Use a local notifier to wait for pipe events. */
29.6
29.7 - file_notifier_t *notifier = client_notifier_local();
29.8 + notifier_t *notifier = client_notifier_local();
29.9
29.10 /* Register the readers for notification. */
29.11