1.1 --- a/fsaccess/op_run.c Sun Jun 02 23:15:39 2024 +0200
1.2 +++ b/fsaccess/op_run.c Tue Jun 04 18:12:02 2024 +0200
1.3 @@ -46,6 +46,7 @@
1.4 #define NUMBER_OF_JOBS 32
1.5
1.6 static file_t *readers[NUMBER_OF_JOBS] = {NULL};
1.7 +static file_t *errors[NUMBER_OF_JOBS] = {NULL};
1.8 static process_t *processes[NUMBER_OF_JOBS] = {NULL};
1.9 static char *programs[NUMBER_OF_JOBS] = {NULL};
1.10 static int next_job = 0;
1.11 @@ -72,6 +73,7 @@
1.12 static void _remove_program(int job_number)
1.13 {
1.14 readers[job_number] = NULL;
1.15 + errors[job_number] = NULL;
1.16 processes[job_number] = NULL;
1.17
1.18 free(programs[job_number]);
1.19 @@ -124,8 +126,11 @@
1.20
1.21 /* Wait for a program to finish, showing its output. */
1.22
1.23 -static int _wait_program(file_t *reader, process_t *process)
1.24 +static int _wait_program(int job_number)
1.25 {
1.26 + file_t *reader = readers[job_number];
1.27 + file_t *error = errors[job_number];
1.28 + process_t *process = processes[job_number];
1.29 notifier_t *notifier = client_notifier_task();
1.30 notifiable_t *notifiable;
1.31 int exitcode;
1.32 @@ -144,12 +149,33 @@
1.33 }
1.34 }
1.35
1.36 + if (error != NULL)
1.37 + {
1.38 + err = client_subscribe(error, NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED, notifier);
1.39 +
1.40 + if (err)
1.41 + {
1.42 + printf("Could not subscribe to pipe notifications: %s\n", l4sys_errtostr(err));
1.43 +
1.44 + if (reader != NULL)
1.45 + client_unsubscribe(reader, notifier);
1.46 +
1.47 + return -1;
1.48 + }
1.49 + }
1.50 +
1.51 err = notify_subscribe(process_notifiable(process), NOTIFY_TASK_ALL, notifier);
1.52
1.53 if (err)
1.54 {
1.55 printf("Could not subscribe to process notifications: %s\n", l4sys_errtostr(err));
1.56 - client_unsubscribe(reader, notifier);
1.57 +
1.58 + if (reader != NULL)
1.59 + client_unsubscribe(reader, notifier);
1.60 +
1.61 + if (error != NULL)
1.62 + client_unsubscribe(error, notifier);
1.63 +
1.64 return -1;
1.65 }
1.66
1.67 @@ -166,15 +192,21 @@
1.68 if (reader != NULL)
1.69 client_unsubscribe(reader, notifier);
1.70
1.71 + if (error != NULL)
1.72 + client_unsubscribe(error, notifier);
1.73 +
1.74 notify_unsubscribe(process_notifiable(process), notifier);
1.75 return -1;
1.76 }
1.77
1.78 - /* Handle input from the reader. */
1.79 + /* Handle input from the readers. */
1.80
1.81 if ((reader != NULL) && (file_notifications(reader) & (NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED)))
1.82 _show_output(reader);
1.83
1.84 + if ((error != NULL) && (file_notifications(error) & (NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED)))
1.85 + _show_output(error);
1.86 +
1.87 /* Handle process termination, obtaining the process state. */
1.88
1.89 if (process_terminated(notifiable))
1.90 @@ -182,6 +214,9 @@
1.91 if ((reader != NULL) && ((process_t *) notifiable->base == process))
1.92 _show_output(reader);
1.93
1.94 + if ((error != NULL) && ((process_t *) notifiable->base == process))
1.95 + _show_output(error);
1.96 +
1.97 _show_status(notifiable);
1.98
1.99 /* If explicitly waiting for this process, remove it from the job list and
1.100 @@ -200,15 +235,21 @@
1.101 if (reader != NULL)
1.102 client_unsubscribe(reader, notifier);
1.103
1.104 + if (error != NULL)
1.105 + client_unsubscribe(error, notifier);
1.106 +
1.107 notify_unsubscribe(process_notifiable(process), notifier);
1.108
1.109 - /* Close the process and pipe. */
1.110 + /* Close the process and pipes. */
1.111
1.112 process_free(process);
1.113
1.114 if (reader != NULL)
1.115 client_close(reader);
1.116
1.117 + if (error != NULL)
1.118 + client_close(error);
1.119 +
1.120 return exitcode;
1.121 }
1.122
1.123 @@ -218,6 +259,7 @@
1.124 {
1.125 process_t *process;
1.126 file_t *output_reader, *output_writer;
1.127 + file_t *error_reader, *error_writer;
1.128 int last_job;
1.129 long err;
1.130
1.131 @@ -241,7 +283,7 @@
1.132 }
1.133 }
1.134
1.135 - /* Create a pipe for process output. */
1.136 + /* Create pipes for process output and errors. */
1.137
1.138 err = client_pipe(&output_reader, &output_writer, O_NONBLOCK);
1.139
1.140 @@ -251,9 +293,18 @@
1.141 return -1;
1.142 }
1.143
1.144 + err = client_pipe(&error_reader, &error_writer, O_NONBLOCK);
1.145 +
1.146 + if (err)
1.147 + {
1.148 + printf("Could not obtain pipe for errors: %s\n", l4sys_errtostr(err));
1.149 + return -1;
1.150 + }
1.151 +
1.152 /* Start the process. */
1.153
1.154 - err = process_spawn(argc, (const char **) argv, input_reader, output_writer, &process);
1.155 + err = process_spawn(argc, (const char **) argv, input_reader, output_writer,
1.156 + error_writer, &process);
1.157
1.158 if (err)
1.159 {
1.160 @@ -262,13 +313,15 @@
1.161 return -1;
1.162 }
1.163
1.164 - /* Release the relinquished end of the output pipe. */
1.165 + /* Release the relinquished end of the output and error pipes. */
1.166
1.167 client_close(output_writer);
1.168 + client_close(error_writer);
1.169
1.170 /* Record the output stream, process and command details. */
1.171
1.172 readers[next_job] = output_reader;
1.173 + errors[next_job] = error_reader;
1.174 processes[next_job] = process;
1.175 programs[next_job] = strdup(argv[0]);
1.176
1.177 @@ -353,7 +406,7 @@
1.178 if (exitcode)
1.179 return exitcode;
1.180
1.181 - return _wait_program(readers[next_job], processes[next_job]);
1.182 + return _wait_program(next_job);
1.183 }
1.184
1.185 /* Show initiated programs. */
1.186 @@ -405,7 +458,7 @@
1.187 return -1;
1.188 }
1.189
1.190 - return _wait_program(readers[job_number], processes[job_number]);
1.191 + return _wait_program(job_number);
1.192 }
1.193
1.194 /* vim: tabstop=2 expandtab shiftwidth=2