CS 355 - Systems Programming:
Unix/Linux with C
Files and Directories
Reference: Molay, Understanding Unix/Linux Programming, Chapter 3.1-3.5
The ls command
Our standard approach to studying a Unix system command:
What does ls do?
ls (without any parameters) prints a list of file names located in the current directory. ls -l shows detailed information about each file. ls is able to distinguish between files and directories.
Read the manual:
LS(1) BSD General Commands Manual LS(1)
NAME
ls -- list directory contents
SYNOPSIS
ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [file ...]
DESCRIPTION
For each operand that names a file of a type other than directory, ls
displays its name as well as any requested, associated information. For
each operand that names a file of type directory, ls displays the names
of files contained within that directory, as well as any requested,
associated information.
If no operands are given, the contents of the current directory are dis-
played. If more than one operand is given, non-directory operands are
displayed first; directory and non-directory operands are sorted sepa-
rately and in lexicographical order.
. . .
Some of the widely used command line options include:
A disk is organized as a tree of directories. Each directory contains files and/or other directories. Every file is located somewhere in a single tree of directories.
How does ls do it?
The basic operation of ls:
open directory
while not end of directory
read directory entry
display file info
close directory
A directory is a special kind of file that contains a list of names of files and directories. It consists of a sequence of records, each with a well documented structure. Each record represents one item - a single file or a single directory. Directories are never empty; each one always contain two special entries: . (current directory) and .. (parent directory).
System calls to work with directory entries:
$ man opendir
DIRECTORY(3) BSD Library Functions Manual DIRECTORY(3)
NAME
closedir, dirfd, opendir, readdir, readdir_r, rewinddir, seekdir, telldir
-- directory operations
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <dirent.h>
int closedir(DIR *dirp);
DIR *opendir(const char *dirname);
struct dirent *readdir(DIR *dirp);
. . .
Structure of dirent:
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename */
};
Can I write ls?
Basic structure of the C code for ls:
main () {
opendir
while(readdir)
print d_name
closedir
}
Implementation of ls:
#include <stdio.h>
#include <dirent.h>
void do_ls(char []);
int main(int ac, char *av[])
{
if (ac == 1)
do_ls( "." );
else
printf("Usage: %s\n", av[0]);
return 0;
}
void do_ls(char dirname[])
{
DIR *dir_ptr; /* the directory */
struct dirent *direntp; /* each entry */
if ((dir_ptr = opendir(dirname)) == NULL)
fprintf(stderr,"ls1: cannot open %s\n", dirname);
else
{
while ((direntp = readdir(dir_ptr)) != NULL)
printf("%s\n", direntp->d_name);
closedir(dir_ptr);
}
}