V22.0477.001 Lab 1: Multifinger

Due date: Wednesday Sep. 11. Don't wait until the last minute.

Introduction

The first programming project is meant to introduce you to some programming tools you'll be using for the rest of the course, particularly the Unix software development environment (g++, autoconf, etc.) and the C++ asynchronous I/O library. You'll start with source to the C++ multifinger program described in Using TCP through sockets. You will modify multifinger to add a timeout, so that it does not sit waiting forever when a finger server hangs. Finally, you should turn in a software distribution of the modified multifinger program.

Fetching and building the source

Start by unpacking the multifinger source in your home directory. On the class machines, you can do so with the following commands:
% tar xzf ~class/src/multifinger.tar.gz
% cd multifinger
% sh ./setup
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
configure.in: 22: required file `./ltconfig' not found
automake: Makefile.am: installing `./INSTALL'
automake: Makefile.am: installing `./COPYING'
+ autoconf
+ set +x
% 
Next, you must configure the software and generate a Makefile--a set of instructions for how to compile the software. For this class, we will use the GNU autoconf and automake tools to generate Makefiles. You will also be linking against the libasync library that is part of SFS. On the class machines, generate the Makefile with the following commands:
% setenv DEBUG -g
% ./configure --with-sfs=/usr/local/fs/debug
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking host system type... i386-unknown-openbsd2.8
...
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
% 
It is very important that you supply the argument --with-sfs=/usr/local/fs/debug to ./configure. If you don't, things will appear to work, but you will get a version of libasync without built-in debugging sanity checks. Your assignment will be linked against debugging libraries for grading, so you want to make sure you get the benefit of the sanity checking while testing the software yourself.

Once the software is configured, you can build multifinger by running gmake. (Note that this is gmake with a g, and not make. At the end of the assignment you will make a software distribution that compiles with any make, but for development you must use gmake which is GNU make.)

% gmake
c++ -DHAVE_CONFIG_H -I. -I. -I.   -I/usr/local/fs/debug ...
/bin/sh ./libtool --mode=link c++  -g -ansi -Wall -Wsign-compare ...
mkdir .libs
c++ -g -ansi -Wall -Wsign-compare -Wchar-subscripts -Werror -Wno-unused ...
% 
That's it! You've now built multifinger. To test it, type:
% ./multifinger dm@class1.scs.cs.nyu.edu class@class1.scs.cs.nyu.edu
You should get finger information for David Mazières and the class account, though not necessarily in that order.

Out-of-directory builds

It is often useful to compile a program in a different directory from the source code. There are several reasons for this. One may want to compile the same source tree multiple times--for example once with debugging, once without. Using two copies of the same source tree would make it a pain to keep the two compiled versions in sync. Another issue is that C++ object files and executables can get pretty large--especially with debugging information. Thus it is considerably faster to compile on a local disk when the source code is not local. Finally, when you have limited backed-up disk space, there is no reason to waste it on huge C++ executables, since these can always be recreated from the source in the event of a disk crash. Autoconf easily supports compiling in a different directory. You simply need to run the configure script from whatever directory you wish the compile to take place. However, when a source tree is being used for out-of-directory builds, you cannot also perform an in-place build. The following example illustrates how one might compile multifinger out-of-directory using local disk space on the machine class2:
% cd multifinger
% gmake distclean
rm -f config.h
rm -f *.tab.c
...
rm -f config.status
% mkdir /home/c2/scratch/student
% cd /home/c2/scratch/student
% mkdir multifinger
% cd multifinger
% setenv DEBUG -g
% ~/multifinger/configure --with-sfs=/usr/local/fs/debug
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
creating Makefile
creating config.h
% gmake
c++ -DHAVE_CONFIG_H -I. -I/home/c/student/multifinger -I. ...
/bin/sh ./libtool --mode=link c++  -g -ansi -Wall -Wsign-compare ...
mkdir .libs
c++ -g -ansi -Wall -Wsign-compare -Wchar-subscripts -Werror ...
% 
(The gmake distclean command cleans up any previous in-directory build, restoring the multifinger directory to its pristine state.)


Adding Timeouts

Now try this:
% ./multifinger dm@slowfinger.scs.cs.nyu.edu
^C
% 
The problem is that while the machine slowfinger accepts finger requests, it never produces any responses. (Machine slowfinger is running a special finger daemon.)

Your assignment is to modify multifinger.C to terminate connections that don't finish producing a response within 10 seconds of the connection setup. That is, after finger::connected is called, your multifinger should spend no more than 10 seconds waiting for the write()s and read()s to complete. If 10 seconds pass without a complete answer from the server, close the file descriptor and move on to another command-line argument. For example, when your multifinger is run thus:

% ./multifinger xxx@slowfinger.scs.cs.nyu.edu class@class1.scs.cs.nyu.edu
it should quickly print the information for the class account, then wait 10 seconds, then exit.

You'll want to use the delaycb function mentioned in Section 6.6 of Using TCP Through Sockets.


Testing

The perl script test-mf contains a few tests to help make sure your multifinger works. You can find this script on the class machines in ~class/bin/test-mf, which should be in your path. Run the tests as follows:
% limit -h descriptors 64
% test-mf
Finger one user: passed
Finger two users: passed
Time out a stuck host in 10 seconds: passed
Combination of good and stuck hosts: passed
More than 64 hosts: passed
Lots of good and stuck hosts: passed
% 
(If the limit command doesn't work, try limit -h openfiles 64 or ulimit -n 64 instead.) If all goes well, test-mf should finish in about 40 seconds and print out messages as above. Your program program will be graded with test-mf, and perhaps other tests.


How/What to hand in

Multifinger

You must submit two files: To build a software distribution, run the command:
% gmake distcheck
rm -rf multifinger-0.0
mkdir multifinger-0.0
chmod 777 multifinger-0.0
...
================================================
multifinger-0.0.tar.gz is ready for distribution
================================================
% 
To turn in your distribution, copy it to the directory ~class/handin/lab1/username where username is your username:
% cp multifinger-0.0.tar.gz ~class/handin/lab1/`logname`/
% 
To create a script file, use the script command. When you run script, everything you type gets saved in a file called typescript. Press CTRL-D to finish the script. The typescript should be copied to the same directory as the software distribution. For example:
% script
Script started, output file is typescript
% limit -h descriptors 64
% ./multifinger dm@slowfinger dm@fastfinger
[dm@fastfinger]
You fingered dm.
% test-mf
Finger one user: passed
Finger two users: passed
...
% ^D Script done, output file is typescript
% cp typescript ~class/handin/lab1/`logname`/
% 
If you have any problems about submission, please contact the instructor. The lab is due before class on Wednesday, September 11th.