C SC 340 Project 1: Gentle introduction to C programming in Linux environment
Spring 2009
Due prior to April 14 lab
Worth 20 of your 100 project points
This is an "individual with a partner" assignment

Overview

This project will introduce you to C programming and working in a Linux command interpreter environment. The C language was developed by Brian Kernighan and Dennis Ritchie at Bell Labs starting in the late 1960s, as an alternative for assembly language for implementing the first Unix operating system. It subsequently became the language of choice for writing operating systems, although now largely supplanted by C++ (another Bell Labs invention). It is an appropriate choice both to implement projects in this course and also to give you experience with a language other than Java. C is not object oriented but most of its syntax is nearly identical to Java. I have posted a page of selected C references on the web that includes links to a couple tutorials on "C for Java Programmers"

Although Linux has a graphical user interface (several, actually), I want you to use a command interface for your projects. Thus the Linux guest OS you will run under VMware is configured for a command interface. By working with the textual command-based interface you are immersed into a development environment used by many operating system developers. If you have used DOS command interfaces on Windows systems, you will be familiar with the concepts. The interface issues a prompt, you type in a command, the command is carried out, its results (if any) are displayed, and another prompt is issued. Unix/Linux command interfaces are called shells, and several are available. The default for our installation is bash, the Bourne Again SHell. This is a pun on the Bourne shell developed for Unix by Steven Bourne.

Your assignment is to begin development of our very own shell, to be called osh, for Otterbein SHell. You will write it in C, and we will start with some basic features now and maybe add more complex ones in a later assignment. A source code framework is provided. Details below.

The term "individual with a partner" means you may work in parallel with a lab partner at adjacent computers and help each other out, but each partner will physically produce and submit his own solution. This will help as you become familiar with the new language and tools.

Basics of composing, compiling and running C programs from bash

There are instructions elsewhere to getting to a Linux command interface. Once there, there are a few basic things you need to do to compose, compile and run C programs.

Getting started with C

Here is relatively simple C program you can type in as is and run, to get some practice. It also is an example of working with text. There are no strings in C, just arrays of characters. The program will ask you to type your name, then respond with the count of characters followed by each individual character.

#include <stdio.h>
#include <string.h>                                                                                                                                   
#define MAX_LENGTH  50                                                      
                                                                            
int main() {                                                                                                                                  
    int i;                                                                  
    char input[MAX_LENGTH];                                                 
    printf("Enter your name -> ");                                          
    scanf("%s",input);                                                      
    printf("\nThanks, %s, your name has %d letters ",input, strlen(input)); 
    for (i=0; i<strlen(input); i++) {                                       
       printf("- %c ", input[i]);                                           
    }                                                                       
    printf("!\n\n");                                                        
    return 0;                                                               
}                                                                           
  
Call it whatever you wish, but use file extension ".c" See me if you have any questions about this program. The first argument of printf() and scanf() is a string containing input/output formatting information. %d means put an integer here, %s means put a string here, %c means put a character here. The following argument(s) contain the values to be formatted. You can output a string literal using only the first argument. Note that Java 5.0 added similar printf methods to its PrintStream class (System.out is a PrintStream object).

Basic structure of a shell (command line interpreter)

A command line interpreter (a.k.a shell) is essentially an infinite while loop. Within the loop is a printf() call to issue the prompt, then a scanf() or fgets() call to receive the user's command, then the logic to recognize which command was entered and finally the logic, usually a switch statement, to carry out that command. The exit command is carried out simply by executing a return 0; statement to terminate the main program.

The logic to recognize a command name should use the strcmp() (string compare) function. It takes two arguments for the two strings to be compared. It returns 0 if they are equal, a negative integer if the first is less lexigraphically and a postive integer if the first is greater.

Your assignment is to extend osh.c

As stated above, osh is a command interpreter. The basic structure of the interpretor is provided for you, in file osh.c. I have pre-installed it in the Linux system image, in directory proj1.

I recommend that you start by copying osh.c from its proj1subdirectory into the main directory then work in the main directory. Once you are logged into Linux, the command:
  cp proj1/osh.c .
will do the copy. The last operand is a single period (".") which is interpreted to represent the current directory.

As provided, osh correctly performs the exit command. It also recognizes the files command but does not perform it.

You will extend osh to implement additional commands as described below.

Make sure you can compile and run the provided osh, before trying to make any changes to it.

Commands to implement

files

Will display a count of the number of files in the "current" directory. For this project, this means the directory from which you ran the program, /home/user. The following C code should get this information:
  int fileCount;
  FILE *in;
  in = popen("ls -l | wc -l", "r");
  fscanf(in, "%d", &fileCount);
  pclose(in);
  // fileCount now contains the count.  You write the code to print it out.

This bit of C code uses the popen function, which carries out a Linux command then opens the command response for reading, as if it were coming from a file. The fscanf function then reads this response into the int variable fileCount. The Linux command itself is a two-command sequence. The first, ls -l, requests a directory listing much like the dir command in DOS. The listing is produced with each filename on a different line. The listing itself is then piped (the vertical bar) as input into the wc -l command, which simply counts the number of lines of input and produces this as its result. The final result is thus the file count. The character just before the wc is a vertical bar. The -l are both lower case L.

You must study the structure of osh.c to understand how it recognizes and performs input commands. Then substitute your code from the files command into it. Then make it run. You need to understand this structure so you'll know how to add additional commands.

display file

Display the contents of the given file. The file is presumed to exist in the underlying directory. Use fopen to open the file, fgetc to read and echo each character (you are finished when fgetc returns EOF), and fclose when finished. Yes, just read it as a stream of characters. If the file does not exist, print the error message: display: file file does not exist (where file is the given filename)

copy [-f] file1 file2

Copy the contents of file1 into file2. The square brackets around -f indicate it is optional. The file1 is presumed to exist in the underlying directory. Use fopen to open the files, fgetc to read, fputc to write(you are finished when it returns EOF), and fclose when finished. As above, process each file as an unstructured sequence of characters. If the first file does not exist, print the error message: copy: file file1 does not exist (where file1 is the first filename). If the second file already exists and the -f (force) option is given, overwrite the existing file. If the second file already exists and the -f option is not given, print the error message: copy: file file2 already exists (where file2 is the second filename).

Scoring

Maximum score is 20 points, broken down as follows: To get full credit for each command, it should be implemented as a function (the files function is already provided), produce correct results, be reasonably documented with comments and self-documenting identifiers, and display an error message if the number of command arguments is wrong. I'll provide you with some test cases.

To Turn In

Send me your completed osh.c file as an email attachment to psanderson@otterbein.edu. To do this from within Linux, right-click on an open area in the VMware window (outside the command window). A pop-up menu of graphical applications will appear. Select Firefox, then go to your preferred web-based email client, e.g., http://webmail.otterbein.edu. Compose the email as usual and you will be able to select osh.c through the normal attachment dialog.


[ C SC 340 | Peter Sanderson | Math Sciences server  | Math Sciences home page | Otterbein ]

Last updated:
Peter Sanderson (PSanderson@otterbein.edu)