cs 241 section week #8 (10/29/09). outline mp5 overview files i/o unix file systems inodes...
DESCRIPTION
MP5 OverviewTRANSCRIPT
CS 241 Section Week #8(10/29/09)
Outline
• MP5 Overview• Files & I/O• UNIX File Systems
– inodes– Directories– Links
MP5 Overview
MP5 Overview• You are to create a “deadlock resilient semaphore” library.
You should implement six functions.• Since we only allow one instance of each resource, you do not
need to implement the Banker’s algorithm for deadlock prevention. You may use a resource allocation graph instead.
• In deadlock detection mode, once a deadlock is detected, you need only send a SIGINT signal. The library does NOT need to worry about how SIGINT is handled.
• The given test cases are far from complete. You should derive your own test cases.
Files and I/O
Unix File Structure/ /bin/ /home/ /home/someuser/ /home/someuser/somefile.txt /usr/ /usr/bin/ /usr/lib/
Internal File Structure
• A file is just a series of bytes:T h i s w n i x f i l e .
Internal File Structure
• A file is just a series of bytes:T h i s w n i x f i l e .
Start of File End of FileCurrent Offset
I/O Libraries in C
kernel system call handler
fileI/O
terminalI/O
pipeI/O
networkI/O
audioI/O
open, read, write, close, select, poll, ...(direct to kernel I/O)
stdio: fopen, fread, fwrite, fclose, ...(buffered I/O)
User Process
Kernel
I/O Libraries in C
kernel system call handler
fileI/O
terminalI/O
pipeI/O
networkI/O
audioI/O
open, read, write, close, select, poll, ...(direct to kernel I/O)
stdio: fopen, fread, fwrite, fclose, ...(buffered I/O)
User Process
Kernel
Buffered I/O Advantages
• We’ve previously used:– printf(…)– fprintf(…)
• Why use buffers?– I/O operations are SLOW!– Every time you write just one byte, you don’t want
to have to access your hard drive.
File Descriptors
• The UNIX operating system uses a file descriptor table to store information about open files:
0 stdin … (sof, eof, offset values, etc)1 stdout …2 stderr …
36 /usr/home/myfile.txt …
open()
• int open(const char *pathname, int flags);
– returns an int, which is the file descriptor– takes in either a relative or full path name– various flag options allow a file to only be
appended to (O_APPEND), opened as write only (O_WRONLY), and more.
open()
• To open a file for reading:int ifd = open(“./input.txt”, O_RDONLY);
• To open OR create a file for writing, with given permissions:– int ofd = open(“output.txt”,
O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
fopen()
• FILE *fopen( const char *filename, const char *mode);
• Rather than an int (file descriptor), fopen returns a FILE stream.
File Permissions
• In UNIX, the file permissions system is relatively basic.– Each file has a single owner and a single group
associated with it.– Each file also has permissions associated with
itself for the owner, members of the group the file is in, and for everyone else.
File Permissions
• These permissions are stored as a three-octal-digit number (000 to 777).
7 5 5
File Permissions
• The most-significant number is the owner’s permission.
7 5 5
Owner
File Permissions
• The middle number is the group’s permission.
7 5 5
Group
File Permissions
• The least-significant number is everyone else’s permission.
7 5 5
Other
File Permissions
• Each octal number is simply three bits: a read bit, a write bit, and an execute bit.
7 5 5
111
1
1
1
10 0
Read:Write:
Execute:
File Permissions
• Thus:– 755 means “everyone can read and execute by file, but
only the owner can write to (edit) my file”– 644 means “everyone can read my file, only the owner can
write to my file, and no one can execute it”– 660 means “only members of the file’s group and the file’s
owner may read or edit the file; others cannot even read it”
Other C file commands!
• close(int fd)– Close the file associated with the given file
descriptor number.– Can you close stdout? Try it.
• fclose(FILE *stream)– fclose can close stdout.
Other C file commands!
• ssize_t read(int fd, void *buf, size_t count);– Read up to count bytes from a file descriptor into
the buffer buf.
• ssize_t write(int fd, void *buf, size_t count);– Write count bytes to a file descriptor from the
buffer buf.
Buffered I/O versions…• size_t fread(void *ptr, size_t size,
size_t count, FILE* stream);– Read up to count*size bytes from a file descriptor into the
buffer ptr.
• size_t fwrite(void *ptr, size_t size, size_t count, FILE* stream);– Write count*size bytes to a file descriptor from the buffer
ptr.
Other C file commands!• off_t lseek(int fd, off_t offset,
int whence);– Seek to a different point in the file.
– lseek(fd, 4, SEEK_SET)• Seek four bytes after the beginning of the file.
– lseek(fd, -4, SEEK_END)• Seek four bytes before the end of the file.
– lseek(fd, 16, SEEK_CUR)• Seek sixteen bytes ahead of the current position.
Other C file commands!• int fseek(FILE *stream,
long int offset, int origin);
– fseek(stream, 4, SEEK_SET)• Seek four bytes after the beginning of the file.
– fseek(stream, -4, SEEK_END)• Seek four bytes before the end of the file.
– fseek(stream, 16, SEEK_CUR)• Seek sixteen bytes ahead of the current position.
UNIX File Systems
UNIX File Systems
inode: per-file data structureAdvantageEfficient for small filesFlexible if the size changes
DisadvantageFile must fit in a single disk partition
UNIX File Systems
inode (continued)Storing Large Files
Directories are files too!
• Directories, like files, have inodes with attributes and pointers to disk blocks
Directories are files too!
• Directories, like files, have inodes with attributes and pointers to disk blocks
• Each directory contains the name and i-node for each file in the directory.
Directories are files too!
• Directories, like files, have inodes with attributes and pointers to disk blocks
• Each directory contains the name and i-node for each file in the directory.
Directory functions#include <unistd.h>
Change the directoryint chdir(const char *path);
Get the current working directorychar *getcwd(char *buf, size_t size);
Directory reading functions#include <dirent.h>
Open the directoryDIR *opendir(const char *dirname);
Close the directoryint closedir(DIR *dirp);
Read the directorystruct dirent *readdir(DIR *dirp);
What’s in a directory entry?struct dirent
Member Fieldschar d_name[256]
Null-terminated file nameino_t d_ino
inode numberunsigned char d_reclen
Length of this recordunsigned char d_type
Type of file (DT_REG, DT_DIR, DT_FIFO, DT_SOCK,
DT_CHR, DT_BLK, DT_UNKNOWN)
Example 1• Use opendir and readdir to print all the filenames in
the current directory:
#include <dirent.h>…DIR *dir;struct dirent *entry;
dir = opendir(“.”);
while(entry = readdir(dir)){printf(“%s\n”,entry->d_name);}
closedir(dir);
• Remember to include error checking!!
Example 2• Modify Example 1 to use the member fields of struct
dirent to display the inode for each file, as well as whether the file is a directory or a regular file.
#include <dirent.h>…DIR *dir;struct dirent *entry;
dir = opendir(“.”);
while(entry = readdir(dir)){printf(“%s %lu\n”,entry->d_name, entry->d_ino);if(entry->d_type == DT_DIR)
printf(“Directory “);else if(entry->d_type == DT_REG)
printf(“File ”);}closedir(dir);
• Remember to include error checking!!
More Directory Functions#include <dirent.h>
Set the position of next readdirvoid seekdir(DIR *dir, off_t offset);
Set the position back to the start of the directoryvoid rewinddir(DIR *dirp);
Get the current location of directory streamoff_t telldir (DIR *dir);
Warning! Warning!opendir and readdir are NOT thread-safe.
DO NOT open two directories at the same time!
How to recursively traverse a directory tree
1. Open the directory (opendir)2. Read each entry (readdir)
– If the file is a directory (d_type == DT_DIR), store it (e.g. in an array of strings).
3. Close the directory (closedir)4. Traverse each saved subdirectory, EXCEPT
'.' and '..'
File information: statUse the stat functions to view the file’s inode’s attributes.
#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>
For a file:int stat(const char *restrict path, struct stat *restrict buf);For a link:int lstat(const char *restrict path, struct stat *restrict buf);For a file descriptor:int fstat(int fildes, struct stat *buf);
Useful fields and macros in struct stat
• stat.st_size– File size, in bytes
• stat.st_mode– File type
• S_ISDIR(stat.st_mode)– Is this a directory?
– User permissions– Etc.
• stat.st_mtime– Time of last modification
Example 3Modify Example 2 to also give file information about each file.
– How large is each file?– Which files are world-readable?– Which files have been modified in the last 24
hours?
Hint: man 2 stat
#include <stdio.h>#include <dirent.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <errno.h>
int main(int argc, char **argv) { DIR *dir; struct dirent *entry;
time_t now = time(NULL);
if((dir = opendir(".")) == NULL) { perror("Can't open directory"); exit(-1); } while((entry = readdir(dir)) != NULL) { struct stat status; if(entry->d_type == DT_DIR) printf("Directory "); else printf("File "); printf("%s is at inode %d\n", entry->d_name, entry->d_ino); if(stat(entry->d_name, &status)) { perror("\tCan't get stat info"); continue; } printf("\t %d bytes, ", status.st_size); if(status.st_mode & S_IROTH) printf("World-readable, "); if(difftime(now,status.st_mtime)<86400) printf("Recently updated, "); } closedir(dir);}
Links
Hard LinkDirectory Entrye.g. all regular files
Symbolic LinkAlso called a Soft LinkA special file that serves as a reference to another file
Link Functions#include <unistd.h>
To create a new link:int link(const char *oldpath, const char *newpath);
Same as ln
To remove an entry from the directory:int unlink(const char *path);
Same as rm
Returns 0 if successful, -1 with errno set if unsuccessful
Hard Link ExampleCommand Lineln /dirA/name1 /dirB/name2
C Code Segmentsif (link("/dirA/name1", "/dirB/name2") == -1) perror("Failed to make a new link in /dirB");
Hard Link Example (contd)
Q: What happens if /dirA/name1 is deleted and recreated?
Hard Link Example (contd)
A: /dirA/name1 and /dirB/name2 are now two distinct files.
Symbolic Link Function#include <unistd.h>
To create a symbolic link:int symlink(const char *oldpath,
const char *newpath);
Same function as command ln –s
Returns 0 if successful, -1 with errno set if unsuccessful
Soft Link ExampleCommand Lineln –s /dirA/name1 /dirB/name2
C Code Segmentsif (symlink("/dirA/name1", "/dirB/name2") == -1) perror("Failed to create a symbolic link in /dirB");
Soft Link Example (contd)
Q: What happens if /dirA/name1 to is deleted and recreated?
Soft Link Example (contd)
A: /dirA/name1 has a different inode, but /dir/name2 still links to it.
Link number• The link number (the st_nlink field in stat)
tells how many directory entries link to this inode. The link number is:– Set to 1 when a file is created– Incremented when link is called– Decremented when unlink is called
• The link number appears in the second column of the output of ls –l. Try it!
• The link number only counts hard links, not soft links.