CSCI 4061 Introduction to Operating Systems
Instructor:
Outline
File Descriptors File redirection Pipes and FIFOs
2
Questions
How does a process access a file? open, read/write
How can we do file redirection? Cmd < file
How to set up pipes? Cmd1 | Cmd2
3
File Descriptors
Identifier returned by the operating system on opening a file
All operations performed on file descriptors Each process has a file descriptor table
Contains currently open file descriptors
Opening a file adds a new entry to the table Closing a file removes its entry from the table
4
1
File Descriptor Table
0 1 2
Close(3); 3 fd1=open(file1,...); 4 fd2=open(file2,...); 5
fd3=open(file3,...);
5
Standard I/O
stdin, stdout, stderr File descriptors 0, 1 and 2
STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO
Always open by default for each process
Standard I/O is just like reading/writing to a file
6
File Descriptor Implementation
0
1 ProcA 2 open(“file1”,...)3 4
0
1 ProcB 2 open(“file2”,...)3 4
7
System File Table
In-memory inode-table
file2
file1
System File Table
Shared kernel data structure
Has an entry for each active call to open Each entry contains
Pointer to inode-table entry for file File offset
Access mode
Count of no. of fds pointing to it
8
2
Inode Table
Shared kernel data structure
Contains an entry for each open file Each entry contains
Information about file type, functions
inode for the file: file information, data location, etc. Count of no. of system table entries pointing to it
9
Opening a File
0
1 ProcA 2 open(“file1”,...) 3 4
0
1 ProcB 2 open(“file2”,...) 3 open(“file1”,...) 4
10
System File Table
In-memory inode-table
file2
file1
Inheriting File Descriptors
After fork(), all file descriptors are copied to the new process
Each process has identical file-descriptor table
Each process has the same files open
The file offset is the same within each file for both
processes
Each file descriptor points to the same sys-table
entry
Reads/writes/lseeks are shared by the processes
11
File Descriptors after fork System File Table
0
1 parent 2 3 4
0
1 child 2 3 4
12
3
File Redirection
Redirect the standard input or output to a file
Input redirection (<): Takes input from a file
instead of keyboard
sort < file
Output redirection (>): Send output to a file instead of display
ls -l > file
13
Duplicating File Descriptors: dup
Creates a copy of fd
Returns new fd where it is copied
Lowest available entry in the file descriptor table
int dup(int fd);
newfd=dup(3);
14
0 1 2 3 4
fd table
system file table
Duplicating File Descriptors: dup2 Creates a copy of fd1 onto fd2
int dup2(int fd1, int fd2);
Closes fd2 if open
0 1 2 3 4
newfd=dup2(3,2);
15
fd table
system file table
File Redirection
How does a process redirect intput/output to a file instead of standard I/O?
E.g.: how do we do: sort < file1
16
4
File Redirection Example
0 1 2 3
/* Open the desired file*/
fd=open(file1, ...);
/* Duplicate fd onto stdin */ newfd=dup2(fd, STDIN_FILENO);
/* Now exec desired command (e.g., sort) */
file1
17
fd table
system file table
Pipes
prog1 | prog2
Allow multiple processes to be linked together Connects output of prog1 to input of prog2
Examples:
ls -l | more
cat foo | sort | head
18
What are Pipes?
Pipes are special files
Pipes are a mechanism for inter-process
communication (IPC)
Allow processes to communicate and share data
Other IPC mechanisms: sockets, shared memory,
semaphores, etc.
A pipe provides a serial data channel between
two processes
Relatively simple IPC mechanism Channel is half-duplex (one-way)
19
How do Pipes Differ from Regular Files?
Sequential read/write
Nameless
Finite-sized memory buffer
No disk I/O involved
Sharing has to be done through inheritance
Disappear as soon as all their ends are closed
20
5
Using Pipes: Overview
Create a pipe: Returns two fds
Share between processes using fork() Close one end of the pipe in each process
One process would read, the other would write Read and write data through the pipe
Close the pipe when done
21
Creating a Pipe: pipe
Creates a pipe and returns its two ends in an array of two fds
fds[0]: for reading
fds[1]: for writing
Output of fds[1] is input of fds[0]
22
int pipe(int fds[2]);
Creating a Pipe: pipe
int pipe(int fds[2]);
Process
fds[0] fds[1]
23
Pipe
Sharing a Pipe across Processes
The only way to share a pipe is via fork()
After fork(), both processes get copies of the pipe fds
fork
Parent
fds[0] fds[1]
Child
fds[0] fds[1]
24
Pipe
6
Pipe I/O: Initialization
Pipe is used to channel data from one process to another
One process would read from pipe
Another process would write to file
Each process closes one end of the pipe
Writing process closes read-end Reading process closes write-end
25
Pipe I/O: Initialization
Suppose the parent wants to read from the pipe and the child wants to write to the pipe
Parent Child
fds[0] fds[1] fds[0] fds[1] xx
26
Pipe
Replacing Standard I/O with Pipe
Example: ls –l | sort
Use dup2 to replace stdin or stdout
Replace stdin with read-end of pipe (fds[0])
Replace stdout with write-end of pipe (fds[1])
Parent Child
fds[0] 0 1 fds[1] xx
27
Pipe
Pipe I/O: Data Sharing
Reading: Done from read-end of pipe
Returns whatever data is in the pipe
Blocks if pipe is empty
Returns EOF if write-end of pipe is closed
Writing: Done from write-end of pipe
Writes into the pipe buffer
Blocks if pipe is full (finite buffer)
Receives SIGPIPE signal if read-end of pipe is
closed
No lseek (treat as character device file)
28
7
FIFOs
Named pipes
Unidirectional shared channels like pipes
Have name and path like a regular file
Persistent even when both ends are closed
Benefits:
Can link unrelated processes Longer lasting than pipes
29
8