Announcements
- Project 8 (last one!) is online if
you have finished #7. Due Friday.
- Final exam is scheduled for Friday May 4, 8-11am
in Maginnes 290
- Today:
Redirection Principles
- Every program gets three open file descriptors at startup
- 0: stdin, 1: stdout, 2: sterr
- These are often attached to the tty
- Most UNIX tools send output to stdout and provide no way to output to a file
- When you want output to a file, we use shell redirection
- Tool is unaware of the redirection
Redirection Principles
- For every process, the kernel maintains an array of open files.
- A file descriptor is an index into that array.
- When you open a file, you ALWAYS get the lowest available spot in that array.
Redirection Techniques
- How to attach stdin to a file
- Method 1: close ... open
- Standard Plumbing: File descriptors 0,1,2 attached to /dev/tty
- 0 for reading, 1 for writing, 2 for writing
- close(0): if the process closes file descriptor 0, that entry in its array of i/o channels is free
- fd = open("file",0): if the process opens another file, that connection is attached to the FIRST FREE entry in the array of i/o channels
- See example stdinredir1.c
Redirection Techniques
- How to attach stdin to a file
- Method 2: open, close, dup, close
- fd = open("data", 0);
- close(0);
- dup(fd);
- close(fd);
Redirection Techniques
- How to attach stdin to a file
- Method 3: uses dup2( origfd, dupfd )
- fd = open("data", 0);
- dup2(fd, 0);
- close(fd);
- dup2 closes 0, and dups fd to 0
- See example stdinredir2.c
Redirection I/O for Another Program
- Q: How does the shell allow "who > userlist.txt"?
Redirection I/O for Another Program
- Q: How does the shell allow "who > userlist.txt"?
- A: It forks() [as we discussed before]
- Before running who, the child close()s fd 1, creat()s userlist.txt which means it is open for writing (at fd 1)
- The exec()d program (who) inherits the file descriptor array and so
who's stdout is attached to userlist.txt
- See example whotofile.c
Understand redirection?
- Q: How to implement:
- who >> userlog
- sort < data
Pipes
- Now let's consider writing "who | sort"
- Q: What really is a pipe?
- A: A one-way data channel in the kernel with a reading end and a writing end
- The system call pipe(2) creates a pipe and connects it to two file
descriptors.
- Usage: pipe(int a[2]);
- a[0] is the file descriptor of the reading end, and a[1] is the file descriptor of the writing end.
Pipes Example
- We could create a pipe and have the same program write into it and read out of it, but that is not particularly useful.
- Typically a pipe is used to send data from one process to another.
- Let's use fork() to create a new process that can share the pipe.
- See pipedemo2.c
- If the child writes into the pipe, the parent can read those bytes.
- We are close to being able to re-implement "who | sort". Shall we try?
Final Technical Details About Pipes
- read() on a pipe blocks until data appear
- write() on a pipe blocks until space is available in the pipe
- When all writers close the writing end, read() returns 0 (i.e., EOF)
- When all readers close the reading end, write() causes SIGPIPE