From 525393246972d14945187602902d5d5e47a9a59e Mon Sep 17 00:00:00 2001 From: Nick Chambers Date: Fri, 19 Apr 2024 11:20:22 -0500 Subject: [PATCH] Demonstrate how to remap stdout --- redirection.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 redirection.c diff --git a/redirection.c b/redirection.c new file mode 100644 index 0000000..c0cba6c --- /dev/null +++ b/redirection.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +int main() { + // The program that will get run, and the file to write to. It is similar to + // the command-line: + // echo "Hello, world!" > ./hello.txt + char *const prog[] = { "echo", "Hello, world!", NULL }; + const char *filename = "./hello.txt"; + + // Create a child process like normal. The parent process will wait for the + // child process, and the child process will execute its program with the + // standard output redirected to the file. + pid_t pid = fork(); + + if(pid == 0) { + // Mimicking the behavior of `>` in the shell, open a handle to the file + // `hello.txt` for writing. If the file doesn't exist, it will be created, + // and if it does exist, truncate the contents of the file. + int handle = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); + + // Map the standard output of the child process to the open file handle. + // This means that whatever writes on the child's standard output stream + // will instead go to the file. The parent's standard output stream will + // remain unchanged. + dup2(handle, STDOUT_FILENO); + + // Execute the program in the child as normal, now that the standard output + // stream has been redirected to the file. + execvp(prog[0], prog); + } else { + // Wait in the parent process for the child to finish running. Once it is + // finished, write the child's process and exit information to its own + // standard output stream, which was not changed by the child's `dup2` + // call. + int status = 0; + wait(&status); + printf("Process %d exited with status %d.\n", pid, status); + } + + return 0; +}