CS 350



CS 350 – Fall 2003

Project 5 12/2/03

Report Due: Wednesday 12/10/03 after class

Objective: We shall explore is interprocess communication using UNIX pipes rather than message queues. This project is also in support of our recent study of file systems since in UNIX pipes are a special for of files. This is a new concept for our course, and is only covered very briefly in the text. Refer to my own document: “UNIX PipesTutorial”, under the Assignments/Exams link for the basics on pipes. This project also introduces the concept of independent concurrent processes in which there is no parent/child/sibling relationship among the processes (problem 3).

This project should be done on a UNIX machine such as the South Pod SUN machines, or directly on bingsuns using telnet. I had problems doing this on Cygwin, so only real UNIX platforms will be recommended. I suggest that you read the “UNIX PipesTutorial” document before proceeding with the project.

You must check all system or significant library call return values for error conditions and take appropriate action. System calls generally return a negative value on abnormal execution. See any book on ANSI C (such as Kernighan & Ritchie) for the return values of standard library calls. Penalties will be given for not doing these checks. You don’t have to check functions such as printf or gets, or fgets!

Problem 1 - Communication Using UNIX Full Duplex Unnamed Pipe Communication:

Write a program which uses UNIX unnamed pipes for two way communications between two concurrent processes (parent and child). The original parent process sets up the pipe link with a pipe call and then forks a child process ( a clone of the parent). First, the parent sends the child a message, the child responds with a message to the parent, the parent send a response back to the child, and finally the child sends a closing message to the parent. A total of four messages are sent and received. clearly label and number the messages so you could tell the sequence and one from another (see below). The parent waits (wait call) for the child to terminate and then terminates itself. Since this problem requires full duplex pipes, it must be run on a bingsun machine. Full duplex is not supported on Linux.

The following header files will be needed:

#include

#include

#include

#include

In addition to the header files you will need the following declared outside of main. Except for errno, the names of the identifiers below are only suggestions - you may use your own naming convention for these variables:

int pid; /* for fork() */

int status; /* for use with the wait(&status) call */

extern int errno; /* used the same way as in project 1 */

int rc; /* for return codes */

char buff[100]; /* a buffer for launching and receiving messages */

int p_des[2]; /* pipe descriptors, p[0] for parent, p[1] for child */

Here are some suggestions for your code – but feel free to it your own way.

In main the parent establishes the pipe link by executing the system call.

rc = pipe(p_des);

The parent then forks a child.

The parent then immediately sends a message to the child as follows:

Using strcpy write the string to buff.

Now execute the “I/O” function call:

rc = write(p_des[0], buff, strlen(buff)+1): /* why the “+1"? */

The parent then waits for an answer by executing the I/O read function against p_des[0], and dumping the message in buff, for example:

rc = read(p_des[0], buff, sizeof(buff));

The parent then responds back one last time

Note that p_des[0] and p_des[1] play the roles of a file descriptors when doing read or write. See any book an ANSI C for details on read and write (for example K & R).

Similarly, the child initially waits for the parent’s message and when it arrives it responds back. After this the child receives the parents last message. The child uses the read and write functions using p_des[1] descriptor.

Each time the parent or child sends or receives a message, it should display it on the screen with appropriate identification of the sending or receiving processes.

You must clearly document the messages sent and received by both processes in your transcript log

Problem 2 - Communication Using UNIX Half Duplex Unnamed Pipe Communication:

Write a program which uses UNIX unnamed pipes for two way communications between two concurrent processes (parent and child). Use the same or similar dialog between parent and child as in problem 1. Distinct from problem 1, you may not assume that the operating system supports full-duplex pipes. Full-duplex will be emulated using two half-duplex pipes. A full-duplex pipe (as in part 1) can be written and read on both ends. The pipe(...) system call will be used twice in the initial parent code, and will result in two distinct pipe descriptors: ptocw[] (“parent to child write”) and pfrmcr[] (“parent from child read”). The parent will send (write) on ptocw[1] and the child will receive (read) on ptocw[0]. Similarly, the parent will receive (read) on pfrmcr[0] and the child will send (write) on pfrmcr[1]. Writing will always be on index 1 of the descriptor and reading will be on index 0 of the descriptor. There is one more complication that must be observed in this approach: The both parent and the child must close down that part of the half-duplex pipe which is not used. The close(pipe_descriptor) is called for each unused descriptor component at each end of both half-duplex pipes. Since the parent writes into ptocw[1] and reads from pfrmcr[0], the parent must do a close on ptocw[0] and pfrmcr[1], likewise the child must do a close on ptocw[1] and pfrmcr[0].

Note, in passing, that close is the same call that would be used to close an I/O file. The call analogous to open(...) would be the pipe(...) call.

Finally if anyone out there is an amateur radio operator, you may recognize the similarity of this approach to communicating on the two-meter band using a repeater. You would transmit on one frequency and receive on another - similar to sending on one pipe and receiving on another.

The following declares are needed outside main():

extern int errno; /* used the same way as in part 1 */

The following declares are needed in or outside of main() for problem 2:

These identifiers are only suggestions - you may use your own naming convention for these variables:

int pid; /* for fork() */

int status; /* for us e with the wait(&status) call */

int rc; /* for return codes */

char buff[100]; /* a buffer for launching and receiving messages */

int pfrmcr[2]; /* incoming pipe: parent reads from child */

int ptocw[2]; /* outgoing pipe: parent writes to child */

See problem 1 on how to use the pipe(...), read(...), and write(...) calls (or see K & R on the latter two).

The functional aspect of the code for problem 2 should be similar to that of problem 1.

Note that after the parent sends its last message, it should close out the two half-duplex channels it was using. The parent then waits (wait call) for the child to terminate and then after printing a message that the child terminated, it terminates itself.

You must clearly document the messages sent and received by both processes in your transcript log.

Problem 3 – Communication Between Unrelated Processes Using UNIX Named Pipes

In this problem there is no forking of a child process. You will write two distinct programs. Lets call them sender() and receiver(). receiver will read a series of strings sent by the sender through a pipe and display them. Information will flow only in one direction: from sender to receiver. sender never receives over the pipe, and receiver never sends over the pipe. Since these two processes have no “family” relationship (no forks used), named pipes must be used. See the instructors document, “UNIX PipesTutorial” for a discussion of named pipes which should be sufficient for doing this problem.

You are probably wondering how to fire off two independently programs concurrently without using fork. Here is how it is done:

receiver may be loaded and run first by making it run in the background. If receiver is the executable name, simply invoke it into the background as follows:

receiver&

the “&” sign after the module name forces it to run in the background. Naturally, receiver blocks and wait for the sender to get fired off and send something. If everything goes OK, the command line should be released back to you. The sender may be invoked in the foreground as any other command or program would be invoked from the command line, for example:

sender xxx yyy zzz

where xxx, yyy and zzz are arguments.

Program Specification:

Both sender and receiver programs should have the following defines and declares:

#include

#include

#include

#define MSGSIZ 63 // 63+1 is suggested size of maximum message (includes null character)

char *fifo = "my_pipe"; // name for the pipe file- use whatever you want

fifo is supposed to be a convenient variable to refer to the pipe name with.

sender specification: The sender will gather a series of messages strings passed as command line arguments separated by spaces and send them to the name pipe for the receiver to read.. However, before it starts sending these messages, it will send an initial special message which is a string indicating the total number of messages on the command line to be sent. This number is argc-1, where argc-1 is one of the arguments for the main function. This number must be first converted to a string using the special itoa() function you used in an ealier project. The receiver will need this information in order to know how many messages to receive. The number of messages must not exceed 99. This program will assume that the pipe is already created by the reader program. Open the pipe as write-only and non-blocking as described in the posted “UNIX PipesTutorial”. After sending the special message giving the number of messages to follow, begin sending these messages from the command line using a loop. Consult the “UNIX PipesTutorial” for details on using the write call to send messages down the pipe. The sender program must be invoked after the receiver program is invoked in the background. As shown above, the sender invocation will appear as:

sender aa bbb ccc delpipe ddd // delpipe is a key word – see below

or

sender aa bbb ccc ddd

where the arguments aa, bbb, ccc, ddd are messages of your choice, and delpipe is an optional special message that tells the receiver to delete the pipe when it is done. delpipe can appear anywhere in the stream of messages.

receiver specification: As described in the UNIX PipesTutorial, create the named pipe using the mkfifo call and open it for reading and writing. Remember that if the mkfifo call returns a –1, you may assume that the names pipe already exists. In this case mkfifo will not create it, and your program simple continues. Do the first read of the named pipe which should be the number of messages to follow. See the UNIX PipesTutorial on how to use the read call to read from the pipe. Next in a loop read the required number of messages sent by the sender and display them on the screen in an easy to read fashion. Check to see if each message is the special delpipe message. If delpipe is received, then make a note of it to be used later. When all the messages have been received, close the pipe and if delpipe was sent, delete the names pipe using the remove(…) system call. See the UNIX PipesTutorial on closing the pipe, and how to delete a pipe. If delpipe was not received in this run, then allow the pipe to remain in your working directory.

Testing the program:

Your reader program should display the messages received from the named pipe an easy to read fashion (see sample output below). In both programs display to the screen all significant events with printfs. Also do a run with and without the delpipe special message, and do an ls –l after the runs to show that the named pipe was created, was allowed to remain and was finally deleted. See a sample run at the below. Make a hardcopy of the log files. Retain all sample runs in their entirety as files on floppies or CD’s.

Questions to be answered

To be added later.

For part 3, the following is sample output:

bingsun2% ls -l

total 23

-rwx------ 1 cs350 users 7218 2003-04-27 01:10 rmsg

-rw-r--r-- 1 cs350 users 1318 2003-04-27 01:10 rmsg.c

-rwx------ 1 cs350 users 7337 2003-04-27 01:10 smsg

-rw-r--r-- 1 cs350 users 1693 2003-04-27 01:10 smsg.c

bingsun2% rmsg&

[1] 9056

bingsun2% smsg aa bbb cccc dd

message received was aa

message received was bbb

message received was cccc

message received was dd

bingsun2% The pipe has been closed

[1] Exit 1 rmsg

bingsun2% ls -l

total 23

prw------- 1 cs350 users 0 2003-04-27 01:12 fifo

-rwx------ 1 cs350 users 7218 2003-04-27 01:10 rmsg

-rw-r--r-- 1 cs350 users 1318 2003-04-27 01:10 rmsg.c

-rwx------ 1 cs350 users 7337 2003-04-27 01:10 smsg

-rw-r--r-- 1 cs350 users 1693 2003-04-27 01:10 smsg.c

bingsun2% rmsg&

[1] 9113

bingsun2% named pipe already exists - will continue

bingsun2% smsg aa bbb cccc delpipe ddd

message received was aa

message received was bbb

message received was cccc

message received was delpipe

message received was ddd

bingsun2% The pipe has been closed

The pipe fifo had been removed

[1] Exit 1 rmsg

bingsun2% ls -l

total 23

-rwx------ 1 cs350 users 7218 2003-04-27 01:10 rmsg

-rw-r--r-- 1 cs350 users 1318 2003-04-27 01:10 rmsg.c

-rwx------ 1 cs350 users 7337 2003-04-27 01:10 smsg

-rw-r--r-- 1 cs350 users 1693 2003-04-27 01:10 smsg.c

PROJECT REPORT REQUIREMENTS:

1. Diskette or CD containing the source code, executables, and any softcopy below.

2. Hardcopy and soft copy of source code.

3. Hardcopy and softcopy of results.

4. The report must contain a transcript documenting the running of each program including the hello.c program.

5. Answer any questions.

6. The source code must be heavily commented.

GRADING:

1. All submitted code must be testable on the bingsuns server, no matter where it was developed.

2. The 100 points for this project is broken down as:

- 50 points if the source code compiles successfully, passes a “desk check” for correctness, is properly

commented, uses good programming techniques, is supplemented with hard and softcopy documentation (see requirements above), etc.

16 points

- 40 points for proper execution of the program(giving correct results). This is verified by hard/softcopy of results and independent testing by the TA. Obviously if your program does not compile, the 16 points cannot be claimed.

- 10 points for answering the questions properly.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download