1.1 --- a/test_files/programs/test_popenv.c Thu May 30 19:26:06 2024 +0200
1.2 +++ b/test_files/programs/test_popenv.c Thu May 30 22:29:00 2024 +0200
1.3 @@ -22,6 +22,9 @@
1.4 #include <stdio.h>
1.5 #include <sys/types.h>
1.6 #include <errno.h>
1.7 +#include <port.h>
1.8 +
1.9 +
1.10
1.11 /* NOTE: To be provided via a header. */
1.12
1.13 @@ -33,6 +36,20 @@
1.14
1.15 static const offset_t TO_TRANSFER = 1024;
1.16
1.17 +/* Transfer data between streams. */
1.18 +
1.19 +static void transfer(FILE *input, FILE *output)
1.20 +{
1.21 + char buffer[TO_TRANSFER];
1.22 + size_t nread;
1.23 +
1.24 + while ((nread = fread(buffer, sizeof(char), TO_TRANSFER, input)))
1.25 + {
1.26 + if (!fwrite(buffer, sizeof(char), nread, output))
1.27 + break;
1.28 + }
1.29 +}
1.30 +
1.31
1.32
1.33 /* List objects in the filesystem image. */
1.34 @@ -41,8 +58,8 @@
1.35 {
1.36 FILE *input, *output, *error;
1.37 pid_t pid;
1.38 - char buffer[TO_TRANSFER];
1.39 - size_t nread;
1.40 + port_t port;
1.41 + event_source_t source;
1.42
1.43 if (argc < 2)
1.44 {
1.45 @@ -62,19 +79,60 @@
1.46
1.47 printf("Process: %d\n", pid);
1.48
1.49 - /* Wait for events on the streams and the process.
1.50 - NOTE: Currently just reading from the process. */
1.51 + /* Monitor the streams and the process. */
1.52 +
1.53 + port = port_create();
1.54 +
1.55 + port_subscribe(port, port_process_source(pid), PORT_PROCESS_ALL);
1.56 +
1.57 + if (stdin != NULL)
1.58 + port_subscribe(port, port_file_source(fileno(stdin)), PORT_INPUT | PORT_CLOSE);
1.59 +
1.60 + port_subscribe(port, port_file_source(fileno(output)), PORT_INPUT | PORT_CLOSE);
1.61 +
1.62 + if (error != NULL)
1.63 + port_subscribe(port, port_file_source(fileno(error)), PORT_INPUT | PORT_CLOSE);
1.64 +
1.65 + /* Wait for events on the streams and the process. */
1.66 +
1.67 + while (1)
1.68 + {
1.69 + if (port_wait(port, &source))
1.70 + {
1.71 + printf("Error waiting for notifications.\n");
1.72 + return 1;
1.73 + }
1.74
1.75 - while ((nread = fread(buffer, sizeof(char), TO_TRANSFER, output)))
1.76 - {
1.77 - if (!fwrite(buffer, sizeof(char), nread, stdout))
1.78 + /* Handle input to this process. */
1.79 +
1.80 + if ((stdin != NULL) && (source == port_file_source(fileno(stdin))))
1.81 + transfer(stdin, input);
1.82 +
1.83 + /* Handle output from the process. */
1.84 +
1.85 + else if (source == port_file_source(fileno(output)))
1.86 + transfer(output, stdout);
1.87 + else if ((error != NULL) && (source == port_file_source(fileno(error))))
1.88 + transfer(error, stderr);
1.89 +
1.90 + /* Handle process termination. */
1.91 +
1.92 + else if (source == port_process_source(pid))
1.93 + {
1.94 + transfer(output, stdout);
1.95 +
1.96 + if (error != NULL)
1.97 + transfer(error, stderr);
1.98 +
1.99 break;
1.100 + }
1.101 }
1.102
1.103 fclose(input);
1.104 fclose(output);
1.105
1.106 - /* NOTE: Error not yet used. */
1.107 + if (error != NULL)
1.108 + fclose(error);
1.109
1.110 return 0;
1.111 }