Review for exam #2
Prof. Brian D. Davison
Computer Science & Engineering, Lehigh University
Announcements
- Friday is Exam #2. Topics include:
- Coding style
- Debugging tools and techniques
- Bash scripting
- UNIX programming
- Today's schedule
- Return project #5: Range 67-100, Average 89
- Collect late HW#5?
- Return homework #5: Range 3.5-9, Average 5.5
- Review solutions to ls and touch
- Review answers to homework #5
- Exam questions?
First, let's revisit the utility touch(1)
- Did you succeed in implementing touch?
- How does your code do it?
- One possible solution can be found
here.
Implementing ls -l
- We started with
a working version of ls.
- Were you able to implement the important details of ls -l?
- Size, last modified
- Owner and group
- Type and permissions
Solution to ls -l
- Need to pull together a number of helpful library functions:
- The lstat() function provides the file details we need.
- The getpwuid() function provides access to user information.
- Use ctime() to convert modification time.
- Use bitwise masks from </sys/stat.h> to extract types and permissions from mode.
- A sample solution (mostly complete) is
here.
Solution to HW#5 -- #2.4
- The FILE structure used by fopen(), getc(), fclose(), etc.
- Difficult to find.
- struct __FILE_TAG in stdio_impl.h is one possibility, as is struct __sFILE in <sys/reent.h&rt;
- Some (older) UNIXes might still have struct FILE defined explicitly, but not modern ones.
- Everyone got 2 points for this one.
Solution to HW#5 -- #2.5
- Saving kernel buffers to disk...
- void sync(void): schedules writes for all information in
memory that should be on disk, including modified super blocks, modified
inodes, and delayed block I/O.
- int fsync(int fildes), int fdatasync(int fildes): writes all modified data and attributes
of the file descriptor fildes to a storage device before returning.
- int fflush(FILE *stream): causes any unwritten data for that
stream to be written to the file.
- int ioctl(int fildes, int command, ... /*arg*/): can flush streams
- int msync(void *addr, size_t len, int flags): writes all
modified copies of pages over the range [addr, addr + len) to
the underlying hardware. (Only useful with mmap().)
- open(2) with O_SYNC, O_DSYNC, etc. options: write operations do not complete until data is written to underlying hardware.
Solution to HW#5 -- #2.9
- lseek() beyond end of file. What happens when you read() or write() to locations well beyond the end?
- For read(): No data transfer will occur past the current end-of-file.
If the starting position is at or after the end-of-file, 0
will be returned.
- For write(): will complete. Creates "holes" in files. Difference in 'logical' size and actual number of bytes written to disk. Bytes in "holes" are 0s.
Try using od -c file to see contents.
Solution to HW#5 -- #3.8
- The execute bit for directories controls use of the directory -- you need execute permissions to cd to the directory, or to access a file in it or a subdirectory of it.
- It is also required to view all info about contents (but not just filename).
- In contrast, read permissions are only needed to view the contents, but not to execute (cd or access to files or subdirectories).
Thus, you can set your home directory to be unreadable (but still executable) by others, and so those who know the names of publicly readable files/directories will still have access (e.g., web home pages).
Solution to HW#5 -- #3.21
- Write a version of cp() that preserves file access time on original, and replicates file access and modification on the copy.
- General approach:
- Uses stat() to collect info about source file
- Copy content as normal
- Uses utime() to (re-)set times on each file