# HG changeset patch # User Paul Boddie # Date 1717100940 -7200 # Node ID 09edc4cd60ce405bfafb16830da93816cd2e1767 # Parent 29bc0785aace922b323c2a492f7e4fc9b64541eb Changed the test to relay input and output to and from the created process. diff -r 29bc0785aace -r 09edc4cd60ce test_files/programs/test_popenv.c --- a/test_files/programs/test_popenv.c Thu May 30 19:26:06 2024 +0200 +++ b/test_files/programs/test_popenv.c Thu May 30 22:29:00 2024 +0200 @@ -22,6 +22,9 @@ #include #include #include +#include + + /* NOTE: To be provided via a header. */ @@ -33,6 +36,20 @@ static const offset_t TO_TRANSFER = 1024; +/* Transfer data between streams. */ + +static void transfer(FILE *input, FILE *output) +{ + char buffer[TO_TRANSFER]; + size_t nread; + + while ((nread = fread(buffer, sizeof(char), TO_TRANSFER, input))) + { + if (!fwrite(buffer, sizeof(char), nread, output)) + break; + } +} + /* List objects in the filesystem image. */ @@ -41,8 +58,8 @@ { FILE *input, *output, *error; pid_t pid; - char buffer[TO_TRANSFER]; - size_t nread; + port_t port; + event_source_t source; if (argc < 2) { @@ -62,19 +79,60 @@ printf("Process: %d\n", pid); - /* Wait for events on the streams and the process. - NOTE: Currently just reading from the process. */ + /* Monitor the streams and the process. */ + + port = port_create(); + + port_subscribe(port, port_process_source(pid), PORT_PROCESS_ALL); + + if (stdin != NULL) + port_subscribe(port, port_file_source(fileno(stdin)), PORT_INPUT | PORT_CLOSE); + + port_subscribe(port, port_file_source(fileno(output)), PORT_INPUT | PORT_CLOSE); + + if (error != NULL) + port_subscribe(port, port_file_source(fileno(error)), PORT_INPUT | PORT_CLOSE); + + /* Wait for events on the streams and the process. */ + + while (1) + { + if (port_wait(port, &source)) + { + printf("Error waiting for notifications.\n"); + return 1; + } - while ((nread = fread(buffer, sizeof(char), TO_TRANSFER, output))) - { - if (!fwrite(buffer, sizeof(char), nread, stdout)) + /* Handle input to this process. */ + + if ((stdin != NULL) && (source == port_file_source(fileno(stdin)))) + transfer(stdin, input); + + /* Handle output from the process. */ + + else if (source == port_file_source(fileno(output))) + transfer(output, stdout); + else if ((error != NULL) && (source == port_file_source(fileno(error)))) + transfer(error, stderr); + + /* Handle process termination. */ + + else if (source == port_process_source(pid)) + { + transfer(output, stdout); + + if (error != NULL) + transfer(error, stderr); + break; + } } fclose(input); fclose(output); - /* NOTE: Error not yet used. */ + if (error != NULL) + fclose(error); return 0; }