Compare commits
3 Commits
1f4326fd68
...
3c64572791
Author | SHA1 | Date |
---|---|---|
Nick Chambers | 3c64572791 | |
Nick Chambers | 5253932469 | |
Nick Chambers | 15aa29126b |
14
README.md
14
README.md
|
@ -1,3 +1,13 @@
|
|||
# shellfish
|
||||
# Shellfish
|
||||
|
||||
Examples demonstrating how command-line shells implement features.
|
||||
## About
|
||||
|
||||
Self-contained examples demonstrating how shells implement common features.
|
||||
Every example can be built and run, however they are not meant to show how to
|
||||
write production-ready software. They only show how the important functions
|
||||
work, and not how to do things like handle and recover from errors.
|
||||
|
||||
## Recommended Order
|
||||
|
||||
1. [exec.c](exec.c)
|
||||
2. [redirection.c](redirection.c)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue