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); } }