Some guidance for programming project of UNIX platform
The project work is a compulsory part of the course. If you don't complete the project, you cannot participate the exam but you have to restart the course.The project work has to be completed at Thursday, May 27, 1999 (24:00). At that point of time you can get 20 credits for your work. If you are late, 2 credits are lost every day. After Wednesday, June 2nd (24:00) there is no hope getting your project accepted any more.
What kind of an application to create?
There is no prespecified topics, but you should choose something on your own. Present your idea to the excersice group advisor in excersice meetin number 4 for approval.Your application should use two or more processes that communicate together, and in addition exploit some files.
Some examples follow.
- Multiple choise questions. A server presents all clients a set of questions in random order, and collects data on correct and incorrect replies. Also the multiple choises for the answers are given in random order for the clients.
- A simple cash register system. There is for example 4 register terminals and a central unit for accounting.
- A program for on-line communication between terminals. Take an example from programs talk and write.
- A game. Reverse, poker, ... Two or more players.
In the implementation, there is no requirement for major network support. This course is not about sockets! You can assume that all workstations have access to a shared file system.
Write a description of your application and implementation highlights. Describe the user interface, usage of processes and files. Clarify what information is passed around, who is responsible of invoking things, and what is stored in the files.
Hand in your plan in excersice meeting number 6.
A careful plan saves a lot of trouble during the implementation!
Good programs need labour
Don't be a snob! Do what is required and leave extra features alone.Well designed is half done:
-
Think about the user of your application, and the
task in which the application should be used.
The most important feature in an application is how
suitable it is for the task.
- Design all features of your application early on. You don't need to implement all of them right away, but if you don't design them before starting the implementation, you may find additions impossible.
- Use proper methods, description techniques, common sense. Iterate. The first version is never perfect. Don't hesitate removing lines of code, pages of documentation, features of your application ... and redesigning when the need arises.
Never copy pieces of code around. Use functions. Don't make your functions longer than 15 lines. Maybe you can extend the reusability of your function with a new parameter. Still, don't overdo it!
Sketch several solutions for your application before deciding which way to go. Evaluate the solutions before proceeding to a more detailed design. Use your advisor for evaluation support!
Read about efficient algorithms and data structures that are somehow close to your problem. Try to find a way to exploit the already existing, already tested algorithms.
Althogh your application may end up being small enough for a single module, make at least two separate modules just for getting the excersice of it.
- Call the main module "main.c".
- Put the prototypes, data structures and other common material to header files ".h". Don't put global variables into the header files, but into main.c.
- Create macros for conditional compilation:
#ifndef _XYZ_H #define _XYZ_H descriptions and definitions #endif _XYZ_H
Always work with best possible taste
Don't write too long sequences of code, but use a proper programming style with clearly structured programs. Use white space. Use the help of indent(1) and cb(1).Avoid special features of the programming language or the programming environment. Don't use nonstandard features. No cryptic expressions! Your project work should compile without any warnings.
Your program should be robust. Test the input, and make sure no core dumps occur.
Use a sensible naming system
- Use descriptive names for variables, so the reader of your program has no need for guesswork. Use CAPITALS for #defined constants and Capital Initials for Type Names.
- Use names that are far enough from each other to avoid missreadings. Don't use too short names. Indexes and loop variables can be i, j, k etc. but otherwise avoid such names.
- Use only English or Finnish names, don't mix languages.
Never use fixed computer names, absolute path names etc. in your programs. If you need to name such things, use environment variables, initialization files, or at least #define them in the header files.
Use #define for constants like table sizes, string lengths, etc.
The maintainability of your code is increased by introducing variables in the block where they are used. For example,
if ( ... ) {
int hide;
...
}
It is easier to notice variables that are not used,
and in addition, your program causes less dynamic memory management
activities.
Use unique path names for named pipes. A user name is not sufficient alone, but causes confusion when several connections are creates.
Use /tmp for temporary files and named pipes. NOTE that Linux computers have a private /tmp directory that can only be accessed via sessions in that computer.
Implement your game so taht it repeats its basic task until an explicit closing command is given.
Remember the provided routines
All UNIX tools are allowed.- Use getopt(3) for command line arguments and options. Remember also strtok(3C).
- User interfaces can be programmed with curses(3X) library.
- Command interpreters etc. can be created with the help of yacc(1) and lex(1) (or bison and flex).
- Routines popen(3S) and pclose(3S) can be helpful if you want to read output of shell commands.
- Be prepared to the termination of your program with ctrl-c or kill command. The program should remove all named pipes and temporary files it created. For this, set signal processors (with sigset(2)) for SIGINT, SIGTERM, SIGPIPE. Remember also atexit(3C).
- When operating with files, make sure that you don't interfere with others. Use file locking, see fcntl(2).
- Consider whether you could use nonblocking transfer and functions select(2) and poll(2).
Make makes it
Prepare your application package so that it compiles, links and works fine with a single make command. This is an extremely compulsory step -- the evaluation of your project ends immediately here, if your makefile is missing or does not work.In your makefile, have targets
- clean, to remove unnecessary files like object files,
- guide, to give guidance in the use of your application,
- demo, to demonstrate the behaviour of your application (this is wellcome, but not always possible).
As the computing centre UNIX environment and the Linux environment at the department differ, please make sure you mention, in which system you tested your product.
If you used something special, like shared memory, mention that explicitly.
Major danger: humans!
Start testing systematically from the beginning, in all phases of your work. Starting from the very first paper model. Try to find as many of the errors as possible as early as possible. Illogical design is the worst to correct late in the programming phase!In UNIX philosophy, prototypes are essential: make a little working core and add more features later on. Naturally, you need to design the whole thing initially, but the implementation is easiest to do step-by-step.
Use gcc -Wall -ansi -pedantic for compilation. Fix your program till the compilation becomes clean.
If everything else fails, try debugging (gbx(1)). Some help can be found with prof(1) and gprof(1) as well.
Be careful not to loose your common sense with the debugger. Never enter the mode where you just fix the obvious without thinking what lead to the failure. A bus errors are not fixed by simply adding if (*P != NULL) all around the program. It just creates logical program errors more difficult to find.
Testing may be easier if you initially take up the idea of a log, and use a private debug option to create test output.
Documentation -- a necessity
This time, for final documentation, you need only to create a manual page and to comment your programs carefully. Take examples by reading man man nad man -s 5 man, and looking into directories /usr/share/man/man? or /usr/share/man/cat?.When commenting your program, the following should apply.
- Each module includes a general comment
- Name and purpose of the module, and into which larger collection it belongs to.
- Programmer's name, date, etc.
- Which functions of this module can be called from other modules.
- Which functions in other modules this module exploits.
Application: Drilli, A multiple choise excersiser
Module: Main.c
Description: Main module presenting the server
Calls: log.c/initialize(), write(), close()
client.c/createclient()
Programmer: T.Eacher
Date: 15.3. 1999
Status: Ready for beta testing
Bugs: Not known
Write comments first, the program code follows easily.
Sending your project work for evaluation
The project work is evaluated by your excersice group advisor.Bundle all relevant files to a tar package (man tar) and send the package via email.
Include the following.
- All source files: program files, header files, etc.
- Manual page
- Makefile (see above for the required targets)
- Test data files for demonstrations. Make sure your demonstrations cover enough cases in your application.
The package for email is prepared for example like this
- Put all required files into a subdirectory "surname".
- Remove all object files and executables.
- Remove all other unnecessary files.
- Give the following command in a working directory one
level above the directory "surname":
tar cvf surname.tar surname - Send the tar-package with any mail program to your advisor.
Evaluation criteria
The project work should be sent for evaluation within the time limits given, the applications should work flawlessly and according to their specifications. The documentation is also required.The total maximum credits are 20,
- 2 for written design report (excersice meeting 6)
- 6 for documentation and maintainability, and
- 12 for user interface and program functionality.
- Carefully written man page.
- Makefile that includes the required parts.
- Proper separation to modules and correct use of header files.
- General comments in all modules, functions, and essential points in the code.
- Sensible naming scheme with variables, constants, etc.
- Good strutuing of the program, appropriate data structures and functions.
- Good programming style, balance with efficient use of C and readability.
- Layout of the program.
- The program should do something natural even in exceptional situations. The advisors will do their best to get a core dump!
- The program should in all terminal occasions clean after itself, i.e., remove temporary files, pipes, return the terminal settings, etc.
- Use interface should be natural, stylish, easy ... The manual page is the last resort for many users!
- There should be no unnecessary or unnatural restrictions in the use of the application.

