Presentation is loading. Please wait.

Presentation is loading. Please wait.

FILE I/O File Descriptors I/O Efficiency File Sharing

Similar presentations


Presentation on theme: "FILE I/O File Descriptors I/O Efficiency File Sharing"— Presentation transcript:

1 FILE I/O File Descriptors I/O Efficiency File Sharing
Atomic Operations 4/24/2019 Nittida

2 File Descriptors To kernel all open files are referred by file descriptors A file descriptor a non-negative integer returned by the kernel (to a process) when a file is opened or created is used to identify a file (to be accessed) as an argument to read or write functions By convention, the Unix shells associate file descriptor 0 with the standard input of a process 1 with the standard output 2 with the standard error File descriptors range from 0 to OPEN_MAX (defined in <limits.h>) 4/24/2019 Nittida

3 File Descriptors open() function #include <sys/types.h>
#include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int oflag, … /*, mode_t mode */); Returns: file descriptor if OK, -1 on error oflag :defined in <fcntl.h> O_RDONLY, O_WRONLY, O_RDWR (one and only one of these) and optional constants from O_APPEND, O_CREATE, O_EXCL, O_TRUNC, O_SYNC, etc 4/24/2019 Nittida

4 File Descriptors creat() function #include <sys/types.h>
#include <sys/stat.h> #include <fcntl.h> int creat(const char *pathname, mode_t mode); Returns: file descriptor opened for write only if OK, -1 on error 4/24/2019 Nittida

5 File Descriptors One defficiency with creat() is
the file is opened for writing if we need to write/read creat () , close (), open () A better way is open (pathname, O_RDWR|O_CREAT|O_TRUNC, mode); 4/24/2019 Nittida

6 File Descriptors lseek() Function #include <sys/types.h>
#include <unistd.h> off_t lseek(int fliedes, off_t offset, int whence); Returns: new file offset if OK, -1 on error whence : SEEK_SET -- offset bytes from the beginning of the file SEEK_CUR -- current value + offset SEEK_END -- size of the file + offset 4/24/2019 Nittida

7 File Descriptors We can seek zero bytes from the current position to determine the current offset offt_t curpos; curpos = lseek(fd, 0, SEEK_CUR); The techinique is used to determine if the file is capable of seeking: if the fd is referred to a pipe or FIFO, lseek will return -1 4/24/2019 Nittida

8 File Descriptors Example
#include <sys/types.h> main() { if (lseek(STDIN_FILENO, 0, SEEK_CUR) == -1) printf(“cannot seek\n); else printf(“seek OK\n); exit(0); } (Test if standard input is capable of seeking) 4/24/2019 Nittida

9 File Descriptors If we invoke this program interactively, we get
$ a.out < /etc/motd seek Ok $ cat < /etc/motd | a.out cannot seek $ a.out < /var/spool//cron/FIFO 4/24/2019 Nittida

10 File Descriptors When lseek() is called, it only records the current file offset within the kernel -- it does not cause any I/O to take place This offset is then used by the next read or write operation The file’s offset can be greater than the file’s size, in which case the next write to the file will extend the file This is referred to as creating a hole in a file and is allowed Any bytes in a file that have not been written are read back as 0 4/24/2019 Nittida

11 File Descriptors (Small) Home Work
Write a program to create a file with a hole in it…. Run your program and demonstrate that it works properly by using these commands ls -l file.hole (if your output file is named file.hole) (to check the size of the file, which must be the same as the number of characters written by the program) od -c file.hole to look at the actual contentx Due : 8/12/2543 4/24/2019 Nittida

12 I/O Efficiency #include <unistd.h> #define BUFFSIZ 16
int main(void) { int n; char buf[BUFFSIZ]; while ((n = read(STDIN_FILENO, buf, BUFFSIZ)) > 0) if (write(STDOUT_FILENO, buf, n) != n) perror(“Write Error”); if (n < 0) perror (“Read Error”); exit(0); } 4/24/2019 Nittida

13 I/O Efficiency This example works for both text file and binary files, since there is no difference between the two to the Unix kernel Modify and Run the program using different values for BUFFSIZ (start from 1, 2, 4, 8, 16, …. ,131072) then show the results of reading a big file ( /kernel/genunix on maliwan) -- redirect your output to /dev/null Time your program everytime and record the required values in the following table. Are there any differences between the result each time? What is/are the causes of this differences (if any)? 4/24/2019 Nittida

14 I/O Efficiency Run your program and fill in the table….. 4/24/2019
Nittida

15 File Sharing Unix supports the sharing of open files between different processes (based on the basic features as ) Several structures provided (& used) by the kernel are: 1. Every process has an entry in the process table within each process table entry is a table of open file descriptors file descriptor flags a pointer to a file table entry 4/24/2019 Nittida

16 2. The kernel maintains a file table for all open files
File Sharing 2. The kernel maintains a file table for all open files Each file table entry contains - the file status flag for the file (read, write, etc.) - the current file offset - a pointer to the v-node table entry for the file 4/24/2019 Nittida

17 File Sharing 3. Each open file has a v-node structure
The v-node contains information about the type of the file and pointers to functions that operate on the file It also contains other information such as the inode This information is read from disk when the file is opened 4/24/2019 Nittida

18 File Sharing Kernel data structures for open files 4/24/2019 Nittida

19 File Sharing Two independent processes with the same file open
4/24/2019 Nittida

20 File Sharing What happens with some certain operations
After each write is complete, the current file offset in the file table entry is incremented by number of bytes written If this causes the current file offset to exceed the current file size, the current file size in the inode table entry is set to the current file offset (the file is extended) If a file is opened with the O_APPEND flag, a corresponding flag is set in the file status flag of the file table entry Each time a write is performed for a file with this append flag set, the current file offset in the file table entry is first set to the current file size from the inode table entry 4/24/2019 Nittida

21 File Sharing The lseek function only modifies the current file offset in the file table entry. No I/O takes place If a file is positioned to its end of file using lseek, all that happens is the current file offset in the file table entry is set to the current file size from the inode table entry 4/24/2019 Nittida

22 Atomic Operations When multiple processes write to the same file, it is possible that unexpected results can arise Consider if (lseek(fd, 0L, 2) < 0) /*position to EOF */ perror(“lseek error”); if (write(fd, buff, 100) != 100) /* and write */ perror(“write error”); 4/24/2019 Nittida

23 Atomic Operations if ( (fd = open(pathname, O_WRONLY)) < 0)
if (errno == ENOENT) { if ( (fd = creat(pathname, mode)) < 0) perror (“create error”); } else perror(“open error”); 4/24/2019 Nittida

24 Atomic Operations Atomic operation method is required to solve this problem ---- > an operation that is composed of multiple steps if the operation is performed atomically, either all the steps are performed, or none is performed it must not be possible for a subset of the steps to be performed 4/24/2019 Nittida


Download ppt "FILE I/O File Descriptors I/O Efficiency File Sharing"

Similar presentations


Ads by Google