#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; }