1.1 --- a/libexec/include/exec/process_creating.h Mon Apr 03 22:10:42 2023 +0200
1.2 +++ b/libexec/include/exec/process_creating.h Tue Apr 04 23:11:00 2023 +0200
1.3 @@ -76,8 +76,6 @@
1.4
1.5 long init_external_pager(l4_cap_idx_t *pager);
1.6
1.7 - long init_process_monitor(l4_cap_idx_t *monitor);
1.8 -
1.9 long configure_task();
1.10
1.11 long allocate_internal_pager();
1.12 @@ -90,10 +88,14 @@
1.13
1.14 long start_program(l4_cap_idx_t monitor, int argc, const char *argv[]);
1.15
1.16 + long _start(int argc, const char *argv[], l4_cap_idx_t process);
1.17 +
1.18 public:
1.19 explicit ProcessCreating(const char *rm_filename, file_t *rm_file);
1.20
1.21 - virtual long start(int argc, const char *argv[], l4_cap_idx_t *process);
1.22 + virtual long init_process_monitor(l4_cap_idx_t *monitor);
1.23 +
1.24 + virtual long start(int argc, const char *argv[], l4_cap_idx_t process);
1.25 };
1.26
1.27 /* vim: tabstop=2 expandtab shiftwidth=2
2.1 --- a/libexec/include/exec/process_creator_resource.h Mon Apr 03 22:10:42 2023 +0200
2.2 +++ b/libexec/include/exec/process_creator_resource.h Tue Apr 04 23:11:00 2023 +0200
2.3 @@ -47,9 +47,11 @@
2.4 void *interface()
2.5 { return static_cast<Opener *>(this); }
2.6
2.7 - /* Process creator interface methods. */
2.8 + /* Local operations. */
2.9
2.10 - virtual long start(int argc, const char *argv[], l4_cap_idx_t *process);
2.11 + virtual long init_process(l4_cap_idx_t *process);
2.12 +
2.13 + virtual long start(int argc, const char *argv[], l4_cap_idx_t process);
2.14
2.15 /* Opener interface methods. */
2.16
3.1 --- a/libexec/lib/src/process_creating.cc Mon Apr 03 22:10:42 2023 +0200
3.2 +++ b/libexec/lib/src/process_creating.cc Tue Apr 04 23:11:00 2023 +0200
3.3 @@ -86,6 +86,7 @@
3.4 long ProcessCreating::init_external_pager(l4_cap_idx_t *pager)
3.5 {
3.6 _exec_pager = new ExternalPager(0, 10 * L4_PAGESIZE);
3.7 + _exec_pager->set_monitor(_monitor);
3.8
3.9 /* Initialise pager regions for the region mapper. */
3.10
3.11 @@ -119,13 +120,7 @@
3.12
3.13 /* Start the monitor in a separate thread. */
3.14
3.15 - long err = ResourceServer(_monitor).start_thread(monitor);
3.16 -
3.17 - if (err)
3.18 - return err;
3.19 -
3.20 - _exec_pager->set_monitor(_monitor);
3.21 - return L4_EOK;
3.22 + return ResourceServer(_monitor).start_thread(monitor);
3.23 }
3.24
3.25 /* Configure the environment for the task. */
3.26 @@ -369,10 +364,8 @@
3.27 program arguments, returning a reference to the process monitor as an object
3.28 for interacting with the process. */
3.29
3.30 -long ProcessCreating::start(int argc, const char *argv[], l4_cap_idx_t *process)
3.31 +long ProcessCreating::_start(int argc, const char *argv[], l4_cap_idx_t process)
3.32 {
3.33 - std::lock_guard<std::mutex> guard(_lock);
3.34 -
3.35 /* Open the program file, handling any error conditions. If successfully
3.36 opened, it will be closed when the process terminates. */
3.37
3.38 @@ -405,10 +398,6 @@
3.39 if (err)
3.40 return err;
3.41
3.42 - err = init_process_monitor(process);
3.43 - if (err)
3.44 - return err;
3.45 -
3.46 err = configure_task();
3.47 if (err)
3.48 return err;
3.49 @@ -421,7 +410,7 @@
3.50 if (err)
3.51 return err;
3.52
3.53 - err = start_program(*process, argc, argv);
3.54 + err = start_program(process, argc, argv);
3.55 if (err)
3.56 return err;
3.57
3.58 @@ -444,5 +433,21 @@
3.59 return L4_EOK;
3.60 }
3.61
3.62 +/* Start the given program, notifying the process monitor upon any error. */
3.63 +
3.64 +long ProcessCreating::start(int argc, const char *argv[], l4_cap_idx_t process)
3.65 +{
3.66 + std::lock_guard<std::mutex> guard(_lock);
3.67 +
3.68 + long err = _start(argc, argv, process);
3.69 +
3.70 + /* Communicate the error using the signal value. */
3.71 +
3.72 + if (err)
3.73 + _monitor->notify_all(NOTIFY_TASK_ERROR, (notify_values_t) {0, err});
3.74 +
3.75 + return err;
3.76 +}
3.77 +
3.78 /* vim: tabstop=2 expandtab shiftwidth=2
3.79 */
4.1 --- a/libexec/lib/src/process_creator_context_resource.cc Mon Apr 03 22:10:42 2023 +0200
4.2 +++ b/libexec/lib/src/process_creator_context_resource.cc Tue Apr 04 23:11:00 2023 +0200
4.3 @@ -67,9 +67,27 @@
4.4 printf("argv[%d] = %s\n", i, argv[i]);
4.5 }
4.6
4.7 - /* Start the new process, obtaining a reference to it. */
4.8 + /* Obtain a reference to a new process and send the reference to the client.
4.9 + This must be done in advance of actually starting the program since the
4.10 + program may complete before the client gets the reference. */
4.11 +
4.12 + long err = _creator->init_process(process);
4.13 +
4.14 + if (!err)
4.15 + err = complete_ProcessCreatorContext_start(*process);
4.16 +
4.17 + /* Attempt to communicate any error from these activities. */
4.18
4.19 - return _creator->start(argc, argv, process);
4.20 + if (err)
4.21 + return err;
4.22 +
4.23 + /* Attempt to actually start the process. Errors cannot be communicated as a
4.24 + reply, so a notification is sent via the process monitor instead by the
4.25 + process creator. */
4.26 +
4.27 + _creator->start(argc, argv, *process);
4.28 +
4.29 + return IPC_MESSAGE_SENT;
4.30 }
4.31
4.32 /* vim: tabstop=4 expandtab shiftwidth=4
5.1 --- a/libexec/lib/src/process_creator_resource.cc Mon Apr 03 22:10:42 2023 +0200
5.2 +++ b/libexec/lib/src/process_creator_resource.cc Tue Apr 04 23:11:00 2023 +0200
5.3 @@ -48,9 +48,14 @@
5.4
5.5 /* ProcessCreator interface methods. */
5.6
5.7 +long ProcessCreatorResource::init_process(l4_cap_idx_t *process)
5.8 +{
5.9 + return _creating.init_process_monitor(process);
5.10 +}
5.11 +
5.12 /* Start the new process, obtaining a reference to it. */
5.13
5.14 -long ProcessCreatorResource::start(int argc, const char *argv[], l4_cap_idx_t *process)
5.15 +long ProcessCreatorResource::start(int argc, const char *argv[], l4_cap_idx_t process)
5.16 {
5.17 return _creating.start(argc, argv, process);
5.18 }
6.1 --- a/libfsclient/include/fsclient/process.h Mon Apr 03 22:10:42 2023 +0200
6.2 +++ b/libfsclient/include/fsclient/process.h Tue Apr 04 23:11:00 2023 +0200
6.3 @@ -58,8 +58,9 @@
6.4
6.5 process_t *process_new();
6.6 void process_close(process_t *process);
6.7 +long process_error(process_t *process);
6.8 void process_init(process_t *process);
6.9 -long process_start(process_t *process, int argc, char *argv[]);
6.10 +long process_start(process_t *process, int argc, const char *argv[]);
6.11
6.12 /* Notification support. */
6.13
7.1 --- a/libfsclient/lib/src/file.cc Mon Apr 03 22:10:42 2023 +0200
7.2 +++ b/libfsclient/lib/src/file.cc Tue Apr 04 23:11:00 2023 +0200
7.3 @@ -95,6 +95,7 @@
7.4 /* Initialise the notifiable section of the structure. */
7.5
7.6 file->notifiable.notifications = 0;
7.7 + file->notifiable.pending_notifications = 0;
7.8 file->notifiable.base = (notifiable_base_t *) file;
7.9 file->notifiable.handler = NULL;
7.10 }
8.1 --- a/libfsclient/lib/src/process.cc Mon Apr 03 22:10:42 2023 +0200
8.2 +++ b/libfsclient/lib/src/process.cc Tue Apr 04 23:11:00 2023 +0200
8.3 @@ -34,6 +34,17 @@
8.4
8.5
8.6
8.7 +/* Utility functions. */
8.8 +
8.9 +static bool _process_terminated(process_t *process)
8.10 +{
8.11 + return ((process->notifiable.notifications & NOTIFY_TASK_SIGNAL) &&
8.12 + (process->notifiable.values.sig == 0)) ||
8.13 + (process->notifiable.notifications & NOTIFY_TASK_ERROR);
8.14 +}
8.15 +
8.16 +
8.17 +
8.18 /* Create a new process object. */
8.19
8.20 process_t *process_new()
8.21 @@ -60,6 +71,16 @@
8.22 process_init(process);
8.23 }
8.24
8.25 +/* Return any process initiation error. */
8.26 +
8.27 +long process_error(process_t *process)
8.28 +{
8.29 + if (process->notifiable.notifications & NOTIFY_TASK_ALL)
8.30 + return process->notifiable.values.val;
8.31 + else
8.32 + return L4_EOK;
8.33 +}
8.34 +
8.35 /* Initialise the given process structure. */
8.36
8.37 void process_init(process_t *process)
8.38 @@ -69,6 +90,7 @@
8.39 /* Initialise the notifiable section of the structure. */
8.40
8.41 process->notifiable.notifications = 0;
8.42 + process->notifiable.pending_notifications = 0;
8.43 process->notifiable.base = (notifiable_base_t *) process;
8.44 process->notifiable.handler = NULL;
8.45 }
8.46 @@ -76,7 +98,7 @@
8.47 /* Start a process using the given arguments.
8.48 NOTE: This does not yet obtain input/output pipes. */
8.49
8.50 -long process_start(process_t *process, int argc, char *argv[])
8.51 +long process_start(process_t *process, int argc, const char *argv[])
8.52 {
8.53 l4_cap_idx_t server = l4re_env_get_cap(ENV_PROCESS_SERVER_NAME);
8.54
8.55 @@ -112,6 +134,7 @@
8.56 /* Initialise the notifiable section of the structure. */
8.57
8.58 process->notifiable.notifications = 0;
8.59 + process->notifiable.pending_notifications = 0;
8.60 process->notifiable.base = (notifiable_base_t *) process;
8.61
8.62 /* Close the context, although a separate mechanism could permit contexts to
8.63 @@ -204,12 +227,8 @@
8.64
8.65 /* Unsubscribe if a termination notification has been received. */
8.66
8.67 - if (!err && (process->notifiable.notifications & NOTIFY_TASK_SIGNAL) &&
8.68 - (process->notifiable.values.sig == 0))
8.69 - {
8.70 + if (!err && _process_terminated(process))
8.71 process_notify_unsubscribe(process, notifier);
8.72 - process_close(process);
8.73 - }
8.74
8.75 return err;
8.76 }
8.77 @@ -225,12 +244,8 @@
8.78
8.79 /* Unsubscribe if a termination notification has been received. */
8.80
8.81 - if (!err && ((*process)->notifiable.notifications & NOTIFY_TASK_SIGNAL) &&
8.82 - ((*process)->notifiable.values.sig == 0))
8.83 - {
8.84 + if (!err && _process_terminated(*process))
8.85 process_notify_unsubscribe(*process, notifier);
8.86 - process_close(*process);
8.87 - }
8.88
8.89 return err;
8.90 }
9.1 --- a/libsystypes/include/systypes/base.h Mon Apr 03 22:10:42 2023 +0200
9.2 +++ b/libsystypes/include/systypes/base.h Tue Apr 04 23:11:00 2023 +0200
9.3 @@ -49,7 +49,8 @@
9.4
9.5 typedef struct
9.6 {
9.7 - unsigned long sig, val; /* signal-specific values */
9.8 + unsigned long sig; /* signal number */
9.9 + long val; /* signal-specific value */
9.10
9.11 } notify_values_t;
9.12
9.13 @@ -62,6 +63,11 @@
9.14 NOTIFY_PEER_CLOSED = 0x004, /* closing files and pipes */
9.15 NOTIFY_FILE_OPENED = 0x008, /* opening files in directories */
9.16 NOTIFY_TASK_SIGNAL = 0x100, /* signal from task */
9.17 + NOTIFY_TASK_ERROR = 0x200, /* error when creating task */
9.18 +
9.19 + /* Combinations of flags. */
9.20 +
9.21 + NOTIFY_TASK_ALL = 0x300,
9.22 };
9.23
9.24 /* Notifiable object types. */
10.1 --- a/tests/dstest_exec.cc Mon Apr 03 22:10:42 2023 +0200
10.2 +++ b/tests/dstest_exec.cc Tue Apr 04 23:11:00 2023 +0200
10.3 @@ -28,6 +28,62 @@
10.4
10.5
10.6
10.7 +static long test_process(int argc, const char *argv[])
10.8 +{
10.9 + /* Obtain the common notifier. */
10.10 +
10.11 + process_notifier_t *notifier = process_notify_task();
10.12 +
10.13 + /* Create a new process structure. */
10.14 +
10.15 + process_t process;
10.16 +
10.17 + process_init(&process);
10.18 +
10.19 + /* Start the process. */
10.20 +
10.21 + long err = process_start(&process, argc, argv);
10.22 +
10.23 + if (err)
10.24 + {
10.25 + printf("Could not start process: %s\n", l4sys_errtostr(err));
10.26 + return err;
10.27 + }
10.28 +
10.29 + printf("Finished program initiation.\n");
10.30 +
10.31 + /* Subscribe to the process for notifications. */
10.32 +
10.33 + err = process_notify_subscribe(&process, NOTIFY_TASK_ALL, notifier);
10.34 +
10.35 + if (err)
10.36 + {
10.37 + printf("Could not subscribe to process: %s\n", l4sys_errtostr(err));
10.38 + return err;
10.39 + }
10.40 +
10.41 + /* Wait for a signal from the process. */
10.42 +
10.43 + err = process_notify_wait_process(&process, notifier);
10.44 +
10.45 + if (err)
10.46 + {
10.47 + printf("Could not wait for process: %s\n", l4sys_errtostr(err));
10.48 + return err;
10.49 + }
10.50 +
10.51 + notify_flags_t flags = process_notifications(&process);
10.52 + notify_values_t values = process_notification_values(&process);
10.53 +
10.54 + printf("End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", flags, values.sig, values.val);
10.55 +
10.56 + err = process_error(&process);
10.57 + process_close(&process);
10.58 + return err;
10.59 +}
10.60 +
10.61 +
10.62 +
10.63 int main(int argc, char *argv[])
10.64 {
10.65 long err;
10.66 @@ -42,52 +98,30 @@
10.67
10.68 process_notifier_t *notifier = process_notify_task();
10.69
10.70 - /* Create a new process structure. */
10.71 -
10.72 - process_t process;
10.73 + /* Start a process for a non-existent program. */
10.74
10.75 - process_init(&process);
10.76 + printf("Start non-existent program...\n");
10.77
10.78 - printf("Start process...\n");
10.79 + const char *bad_argv[] = {"non_existent_program"};
10.80
10.81 - /* Start a process for the given program. */
10.82 -
10.83 - err = process_start(&process, argc - 1, argv + 1);
10.84 + err = test_process(1, bad_argv);
10.85
10.86 - if (err)
10.87 + if (!err)
10.88 {
10.89 - printf("Could not start process: %s\n", l4sys_errtostr(err));
10.90 + printf("Non-existent program was apparently successfully started.\n");
10.91 return 1;
10.92 }
10.93
10.94 - printf("Finished program initiation.\n");
10.95 + printf("Non-existent program result: %s\n", l4sys_errtostr(err));
10.96 +
10.97 + /* Start a process for the given program. */
10.98
10.99 - /* Subscribe to the process for notifications. */
10.100 + printf("Start process...\n");
10.101
10.102 - err = process_notify_subscribe(&process, NOTIFY_TASK_SIGNAL, notifier);
10.103 + err = test_process(argc - 1, (const char **) argv + 1);
10.104
10.105 if (err)
10.106 - {
10.107 - printf("Could not subscribe to process: %s\n", l4sys_errtostr(err));
10.108 return 1;
10.109 - }
10.110 -
10.111 - /* Wait for a signal from the process. */
10.112 -
10.113 - err = process_notify_wait_process(&process, notifier);
10.114 -
10.115 - if (err)
10.116 - {
10.117 - printf("Could not wait for process: %s\n", l4sys_errtostr(err));
10.118 - return 1;
10.119 - }
10.120 -
10.121 - notify_flags_t flags = process_notifications(&process);
10.122 - notify_values_t values = process_notification_values(&process);
10.123 -
10.124 - process_close(&process);
10.125 -
10.126 - printf("End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", flags, values.sig, values.val);
10.127
10.128 process_notify_close(notifier);
10.129
11.1 --- a/tests/dstest_exec_many.cc Mon Apr 03 22:10:42 2023 +0200
11.2 +++ b/tests/dstest_exec_many.cc Tue Apr 04 23:11:00 2023 +0200
11.3 @@ -57,7 +57,7 @@
11.4
11.5 /* Start a process for the given program. */
11.6
11.7 - err = process_start(&process, argc - 2, argv + 2);
11.8 + err = process_start(&process, argc - 2, (const char **) argv + 2);
11.9
11.10 if (err)
11.11 {
11.12 @@ -69,7 +69,7 @@
11.13
11.14 /* Subscribe to the process for notifications. */
11.15
11.16 - err = process_notify_subscribe(&process, NOTIFY_TASK_SIGNAL, notifier);
11.17 + err = process_notify_subscribe(&process, NOTIFY_TASK_ALL, notifier);
11.18
11.19 if (err)
11.20 {
11.21 @@ -90,9 +90,9 @@
11.22 notify_flags_t flags = process_notifications(&process);
11.23 notify_values_t values = process_notification_values(&process);
11.24
11.25 - process_close(&process);
11.26 + printf("[%d/%d] End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", i, num_processes, flags, values.sig, values.val);
11.27
11.28 - printf("[%d/%d] End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", i, num_processes, flags, values.sig, values.val);
11.29 + process_close(&process);
11.30 }
11.31
11.32 process_notify_close(notifier);