Files and Directories: ls and touch
Prof. Brian D. Davison
Computer Science & Engineering, Lehigh University
Announcements
- Reminder: Homework 5 online (from book), due Monday
- Monday's class will be in the lab
- Today's schedule
- Short Quiz #8: Scripting and Programming UNIX Utilities
- Review of some slides from Wednesday
- Continue Understanding UNIX Programming
Writing ls (using same approach)
- So writing ls should be easy...
- Open directory
- Repeatedly read directory entry and display entry
- Close directory
- Much like the who command
Directories
- Q: What is a directory?
- A: A special kind of file that contains a list of files and/or other directories
- Note: Every directory contains special entries . and ..
- Q: Can we use file operators on directories? (e.g., open, read, etc.)
- A: Once, there was no other way...
Reading Directories
- A2: Even if you could read all directories as files, you don't want to --
particularly since UNIX supports a variety of directory formats
- Q: So how do we read directories?
man -k direct
man -k direct | grep read
- A: opendir(), readdir(), closedir()
Using Directory Functions
#include <dirent.h>
opendir(name)
- Creates a connection, returns a DIR *
readdir(DIR *)
- Gets next record from directory, returns struct dirent *
closedir(DIR *)
Writing first version of ls.c
main()
opendir()
while ( readdir() )
print d_name
closedir()
return 0
- Let's compile and run the code
Something a little different
- Each student will help write ls, five minutes at a time!
How well does our ls work?
- No columns -- we can fix that, might be interesting
- Not sorted -- solution is to use qsort() on array
- No -a option (to list all files) -- solution is simple
- No -l option -- hmm.... let's come back to that.
First, let's consider the utility touch(1)
- What is touch? What does it do?
- How does it work?
- Can we implement it? Let's try.
How do we add -l to our ls?
- Q: What does -l display?
- A: modtime, size, owner, group, links, type, permissions
- Q: Where can we learn about these?
- A: As always, search the manual
- Result: the stat() system call
How does stat() work?
- int stat(char *name, struct stat *buf)
- struct contains
- st_mode
- st_uid
- st_gid
- st_size
- st_links
- st_mtime
- So we can modify ls to provide -l features using stat() on the filename
How well does our ls -l work?
- Perfect: filenames, filesizes
- We can use ctime() to convert the mod time
- Owner and group info are stored as numbers, so we need to map them to names
- What about type? permission?
Where are type and permissions stored?
- st_mode is a 16 bit value. Within it, we have
- four bits for the file type
- three bits for suid, sgid, and sticky bit
- nine bits for owner, group and world rwx permissions
- So we will use subfield coding
- Much like telephone numbers, IP addresses, etc.
UIDs and GIDs
- UIDs and GIDs from stat() are just numbers
- How can we convert them to names?
- Then we can finish our ls -l