CS 241 Section Week 8 102909 Outline MP

  • Slides: 55
Download presentation
CS 241 Section Week #8 (10/29/09)

CS 241 Section Week #8 (10/29/09)

Outline • MP 5 Overview • Files & I/O • UNIX File Systems –

Outline • MP 5 Overview • Files & I/O • UNIX File Systems – inodes – Directories – Links

MP 5 Overview

MP 5 Overview

MP 5 Overview • You are to create a “deadlock resilient semaphore” library. You

MP 5 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

Files and I/O

Unix File Structure / /bin/ /home/someuser/somefile. txt /usr/bin/ /usr/lib/

Unix File Structure / /bin/ /home/someuser/somefile. txt /usr/bin/ /usr/lib/

Internal File Structure • A file is just a series of bytes: T h

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

Internal File Structure • A file is just a series of bytes: T h Start of File i s w Current Offset n i x f i l e . End of File

I/O Libraries in C User Process stdio: fopen, fread, fwrite, fclose, . . .

I/O Libraries in C User Process stdio: fopen, fread, fwrite, fclose, . . . (buffered I/O) open, read, write, close, select, poll, . . . (direct to kernel I/O) kernel system call handler Kernel file I/O terminal I/O pipe I/O network I/O audio I/O

I/O Libraries in C User Process stdio: fopen, fread, fwrite, fclose, . . .

I/O Libraries in C User Process stdio: fopen, fread, fwrite, fclose, . . . (buffered I/O) open, read, write, close, select, poll, . . . (direct to kernel I/O) kernel system call handler Kernel file I/O terminal I/O pipe I/O network I/O audio I/O

Buffered I/O Advantages • We’ve previously used: – printf(…) – fprintf(…) • Why use

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

File Descriptors • The UNIX operating system uses a file descriptor table to store information about open files: 0 1 2 stdin stdout stderr 36 /usr/home/myfile. txt … (sof, eof, offset values, etc) … … …

open() • int open(const char *pathname, int flags); – – – returns an int,

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”,

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

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 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-octaldigit number (000 to 777).

File Permissions • These permissions are stored as a three-octaldigit number (000 to 777). 7 5 5

File Permissions • The most-significant number is the owner’s permission. Owner 7 5 5

File Permissions • The most-significant number is the owner’s permission. Owner 7 5 5

File Permissions • The middle number is the group’s permission. Group 7 5 5

File Permissions • The middle number is the group’s permission. Group 7 5 5

File Permissions • The least-significant number is everyone else’s permission. Other 7 5 5

File Permissions • The least-significant number is everyone else’s permission. Other 7 5 5

File Permissions • Each octal number is simply three bits: a read bit, a

File Permissions • Each octal number is simply three bits: a read bit, a write bit, and an execute bit. Read: Write: Execute: 7 5 5 1 1 0 1

File Permissions • Thus: – 755 means “everyone can read and execute by file,

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

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

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

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

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

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

UNIX File Systems inode: per-file data structure Advantage Efficient for small files Flexible if

UNIX File Systems inode: per-file data structure Advantage Efficient for small files Flexible if the size changes Disadvantage File must fit in a single disk partition

UNIX File Systems inode (continued) Storing Large Files

UNIX File Systems inode (continued) Storing Large Files

Directories are files too! • Directories, like files, have inodes with attributes and pointers

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

Directories are files too! • Directories, like files, have inodes with attributes and pointers to disk blocks • Each directory contains the name and inode for each file in the directory.

Directories are files too! • Directories, like files, have inodes with attributes and pointers

Directories are files too! • Directories, like files, have inodes with attributes and pointers to disk blocks • Each directory contains the name and inode for each file in the directory.

Directory functions #include <unistd. h> Change the directory int chdir(const char *path); Get the

Directory functions #include <unistd. h> Change the directory int chdir(const char *path); Get the current working directory char *getcwd(char *buf, size_t size);

Directory reading functions #include <dirent. h> Open the directory DIR *opendir(const char *dirname); Close

Directory reading functions #include <dirent. h> Open the directory DIR *opendir(const char *dirname); Close the directory int closedir(DIR *dirp); Read the directory struct dirent *readdir(DIR *dirp);

What’s in a directory entry? struct dirent Member Fields char d_name[256] Null-terminated file name

What’s in a directory entry? struct dirent Member Fields char d_name[256] Null-terminated file name ino_t d_ino inode number unsigned char d_reclen Length of this record unsigned 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

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(“%sn”, entry->d_name); } closedir(dir); • Remember to include error checking!!

Example 2 • Modify Example 1 to use the member fields of struct dirent

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 %lun”, 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 readdir void seekdir(DIR

More Directory Functions #include <dirent. h> Set the position of next readdir void seekdir(DIR *dir, off_t offset); Set the position back to the start of the directory void rewinddir(DIR *dirp); Get the current location of directory stream off_t telldir (DIR *dir);

Warning! opendir and readdir are NOT threadsafe. DO NOT open two directories at the

Warning! opendir and readdir are NOT threadsafe. DO NOT open two directories at the same time!

How to recursively traverse a directory tree 1. Open the directory (opendir) 2. Read

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: stat Use the stat functions to view the file’s inode’s attributes. #include

File information: stat Use 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

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 3 Modify Example 2 to also give file information about each file. –

Example 3 Modify 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.

#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 status; if(entry->d_type == DT_DIR) printf("Directory "); else printf("File "); printf("%s is at inode %dn", entry->d_name, entry->d_ino); if(stat(entry->d_name, &status)) { perror("t. Can'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 Link Directory Entry e. g. all regular files Symbolic Link Also called

Links Hard Link Directory Entry e. g. all regular files Symbolic Link Also called a Soft Link A 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,

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 Example Command Line ln /dir. A/name 1 /dir. B/name 2 C Code

Hard Link Example Command Line ln /dir. A/name 1 /dir. B/name 2 C Code Segments if (link("/dir. A/name 1", "/dir. B/name 2") == -1) perror("Failed to make a new link in /dir. B");

Hard Link Example (contd) Q: What happens if /dir. A/name 1 is deleted and

Hard Link Example (contd) Q: What happens if /dir. A/name 1 is deleted and recreated?

Hard Link Example (contd) A: /dir. A/name 1 and /dir. B/name 2 are now

Hard Link Example (contd) A: /dir. A/name 1 and /dir. B/name 2 are now two distinct files.

Symbolic Link Function #include <unistd. h> To create a symbolic link: int symlink(const char

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 Example Command Line ln –s /dir. A/name 1 /dir. B/name 2 C

Soft Link Example Command Line ln –s /dir. A/name 1 /dir. B/name 2 C Code Segments if (symlink("/dir. A/name 1", "/dir. B/name 2") == -1) perror("Failed to create a symbolic link in /dir. B");

Soft Link Example (contd) Q: What happens if /dir. A/name 1 to is deleted

Soft Link Example (contd) Q: What happens if /dir. A/name 1 to is deleted and recreated?

Soft Link Example (contd) A: /dir. A/name 1 has a different inode, but /dir/name

Soft Link Example (contd) A: /dir. A/name 1 has a different inode, but /dir/name 2 still links to it.

Link number • The link number (the st_nlink field in stat) tells how many

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.