Title: Module 4: Processes
1Operating SystemsLecture 11 UNIX Pipes Read
Handout "An Introduction to Concurrency..."
2File Redirection in UNIX
Everything in UNIX is a file. Commands are
files. Pipes read and write to a buffer that is a
file. Many UNIX commands read and write to stdin
and stdout. These are also treated as
files. stdin has a special file descriptor
0 stdout has a special file descriptor 1 To
redirect input or output we attach the file
descriptors for stdin or stdout to the file we
want to redirect the input (or output) to.
3Steps for File Redirection
- To redirect the input (or output) from stdin (or
stdout) to a file we must carry out the following
steps - Open the file for reading (or writing).
- Attach the file descriptor for stdin (or stdout)
to the newly opened file. - Close the file descriptor for the opened file.
4Opening a File
Use the command, open( ) to open a file for
reading or writing. int fd // file
descriptor fd open( fileName, FLAGS,
permissions) open( ) opens the file whose name
is given by the string, fileName, and returns an
integer file descriptor to be used to access the
file. fileName is a string, giving the name of
the file. FLAGS a list of flags that indicate
read/write status of file. permissions
Indicates read/write permissions for the file
(only needed if creating a new file).
5FLAGS for open( )
The flags indicate the read/write status of the
file O_RDONLY Open the file for
reading. O_WRONLY Open the file for
writing. O_CREAT Create the file if it doesn't
exist. O_APPEND Open the file for
appending O_TRUNC Truncate the length of the file
to zero. Flags can be combined by a bitwise OR
() fd open(myFile, O_WRONLY
O_APPEND) Other flags are described on the man
page for open.
6File Permissions
File read/write permission can be indicated as a
3 digit integer, with each digit indicating the
permissions for the user/group/others. Each
digit represents a 3 bit binary number, with each
bit representing read, write or execute
permission. 1 indicates permission for that
function 0 indicates no permission for that
function Example Permission rwxr-xr-- 1111
01100 7 5 4 fd open(myFile, O_WRONLY
O_CREAT, 754)
7Attaching the File Descriptor to stdin (or stdout)
Use the function dup2( ) to attach the file
descriptor for our open file to stdin (or
stdout) dup2( fd, 0) // redirect stdin to
file with descriptor fd dup2( ) causes the
second file descriptor (in this case the
descriptor for stdin) to refer to the same file
as the first file descriptor (in this case our
open file). To redirect to stdout, use dup2(fd,
1). Once the input or output is redirected, you
should close the new file descriptor (it is no
longer needed) close(fd)
8Example Redirect Output
//The preliminaries include ltiostream.hgt include
ltsys/wait.hgt include ltfcntl.hgt include
ltstdlib.hgt include ltunistd.hgt int main(void)
int cpid char myFile20 int myFileD
int done, status
9Redirect output (continued)
cout ltlt "Enter output file name " cin gtgt
myFile myFileD open(myFile, O_WRONLY
O_CREAT O_TRUNC, 0700) cpid fork( ) if
(cpid 0) //Child process dup2(myFileD,
1) //Attach stdout to file
close(myFileD) //myFileD no longer needed
execlp("ls", "ls", "-l", NULL) //Execute ls
command else //Parent process done
wait(status) //wait for child to finish
cout ltlt "All done!" ltlt endl return 0
Demo 1
10Redirect input
cout ltlt "Enter input file name " cin gtgt
myFile myFileD open(myFile, O_RDONLY)
cpid fork( ) if (cpid 0) //Child
process dup2(myFileD, 0) //Attach stdin to
file close(myFileD) //myFileD no longer
needed execlp("wc", "wc", "-l",
NULL) //Execute wc command else //Parent
process done wait(status) //wait for
child to finish cout ltlt "All done!" ltlt endl
return 0
Demo 2
11UNIX Pipes
Unix pipes allow communication between two
processes using a buffer. One process writes to
the buffer. One process reads from the
buffer. The communication is unidirectional. The
buffer is accessed using a file
descriptor. (Recall that everything in UNIX is a
file).
12Creating a pipe
A pipe is represented by an integer array of
length 2. int fd2 fd0 file descriptor for
reading from the pipe. fd1 file descriptor for
writing to the pipe. Use the pipe( ) function to
initialize the pipe pipe(fd) (This should be
done by the parent process). To communicate
using a pipe One process opens fd0 (for
reading) and closes fd1. The other process
opens fd1 (for writing) and closes fd0.
13define MAX 25 int main(void) int cpid int
fd2 char lineMAX int done, status
pipe(fd) cpid fork( ) if (cpid 0)
cout ltlt "The child process is active." ltlt endl
close(fd1) //close
writing end of pipe read(fd0, line, MAX)
//read a max of 25 chars into line cout ltlt
"The string received is " ltlt line ltlt endl
else cout ltlt "The parent is active." ltlt
endl close(fd0)
//close reading end of pipe
write(fd1, "Your parent is calling", 23)
//write to pipe done wait(status)
cout ltlt "All done!" ltlt endl return 0
Demo 3
14Using the pipes to redirect stdin and stdout
In UNIX, pipes are often used to direct the
output of one command to the input of a second
command. Example who wc -l who normally
directs the output to stdout. We want to
redirect the output to the writing end of the
pipe. wc normally reads input from stdin. We
want to redirect that input to come from the
reading end of the pipe. We redirect the input
and output the same way we did for file
redirection.
15Example The first child
int main(void) int cpid, cpid2 int fd2
int done, status pipe(fd) cpid fork(
) if (cpid 0) cout ltlt "The first
child process is active." ltlt endl
close(fd1) //close writing end of pipe
dup2(fd0, 0) //redirect std in to reading
end of pipe close(fd0) execlp("wc",
"wc", "-l", NULL)
16Example (cont'd) The second child
else cpid2 fork() if ( cpid2
0) cout ltlt "The second child is active."
ltlt endl close(fd0) //close reading
end of pipe dup2(fd1, 1) //redirect
stdout to writing end of pipe
close(fd1) execlp("who", "who", NULL)
17Example (cont'd) The parent
else cout ltlt "The parent is active."
ltlt endl close(fd0) //close reading
end of pipe close(fd1) //close
writing end of pipe done waitpid(cpid,
status, 0) //wait for children done
waitpid(cpid2, status, 0) cout ltlt "All
done!" ltlt endl return 0
Demo 4