CS 61c -- Summer 2006

Project 1

 

This project is due before the end of the day of Monday, July 17th. This is an individual assignment; you must work alone. Submit your solution, a file named directory.c, as proj1 .

Goals

This project is intended to give you substantial practice with C pointers, linked structures, and use of malloc and free .

Background

Most of you have had experience working with the UNIX operating system. UNIX provides a tree-structured file system and operations for navigating around it. In this project, you will work with a command interpreter, implementing commands that create and delete nodes in a tree that loosely simulates a UNIX directory.1

The nodes in the tree represent text files and directory files . A directory file contains zero or more text files and zero or more directory files. A text file contains characters, and corresponds to a leaf in the tree. (An empty directory also corresponds to a leaf.) Each file has a name, a sequence of non-whitespace characters. The root of the tree represents the root directory in the file system. The working directory is also a directory in the file system; the cd command (for "change directory") lets the user move the working directory up and down in the tree.

The commands to be supported by the interpreter are described in the table on the next page. They are simpler than their counterparts in the UNIX shell: as noted above, there are only two kinds of files; no command options (normally specified using "-") are allowed; all arguments refer to files in the working directory except as specified in the table; and there is no special handling of "/" within file names.

command

number of arguments

comments

pwd

0

Prints the full path name of the working directory.

cd

1

Changes the working directory to that specified by the argument, which must be one of the following:

  • the name of a directory in the working directory;
  • the string "..", meaning the parent directory (the root is its own parent); or
  • the string "/", meaning the root directory.
mkdir

1

Creates a directory with the given name. The working directory must not already contain a file with that name.

ls

0 or 1

If given without arguments, prints the names of files in the working directory in alphabetical order; if given with the name of a text file in the working directory, prints that name; if given with the name of a directory in the working directory, prints the names of files in that directory in alphabetical order by name; otherwise prints nothing.

rmdir

1

Removes the directory with the given name. The working directory must contain the named directory, and the named directory must be empty.

create

1

Creates a "text file" with the given name, then reads the contents of the file from standard input. The working directory must not already contain a file with the given name.

cat

≥ 1

Prints the contents of the text files named by the arguments.

rm

1

Removes the named text file from the working directory. The working directory must contain the named file.

Table of commands to be supported by the project 1 command interpreter

The directory ~cs61c/public_html/su06/hw/proj1 contains four files: a Makefile, dirmain.c , directory.h , and directory.c . The main program in dirmain.c repeatedly reads a command from standard input, checks that it is syntactically correct, and if so calls one of the functions in directory.c to execute the command. The file directory.h contains declarations for functions that access and modify the directory tree. The file directory.c contains the actual definitions of these functions, as well as a struct entryNode declaration that represents a file (directory or text file). It also provides complete implementations for commands that don't change the directory structure, namely cd , pwd , ls , and cat . Don't change these functions or the entryNode declaration. You need only submit your directory.c file. Changes to other files will not be accepted.

Each entryNode stores the name of the corresponding file (that is, a pointer to the file name's first character), a pointer to the file in the same directory whose name is next in alphabetical order, an indicator of whether the file is a text file or a directory file, a pointer to the parent node, and a pointer to the contents of the file (text for a text file, a list of files, ordered alphabetically by file name, for a directory file). Figure 1 contains a sample directory and its representation in entryNodes .

A sample directory:

Its implementation:

Project

You are to complete the remaining functions, which initialize the file system and implement the mkdir , create , rmdir , and rm commands. You may provide auxiliary functions. Detailed information about the behavior of these commands follows.

file system initialization
returns a pointer to a directory entryNode with name = "/", no siblings, parent = itself, and no children.

mkdir
creates an entryNode for the new directory, copying the argument string into dynamically allocated space for the directory name, then adds the new entry to the working directory's entries list.

create
creates an entryNode for the new text file, copying the argument string into dynamically allocated space for the file name. It then reads the contents of the simulated text file from standard input, and stores it into suitably allocated dynamic storage. (You should not assume any bound on the amount of text.) Two consecutive carriage returns indicates the end of this text. The first is stored in the contents string, followed by a null character; the second carriage return is not stored. The new entry is then added to the working directory's entries list.

rmdir , rm
removes the named file from the working directory's entries list, and frees all dynamically allocated storage associated with the file

 


1. An actual UNIX file system is organized somewhat differently; see The UNIX Programming Environment , by Brian Kernighan and Rob Pike (Prentice-Hall, 1984), for further information.