Transcript File I/O

File I/O





open
close
lseek
read and write – unbuffered I/O
dup and dup2
File Descriptors

Kernel maintains file descriptors to
reference open files


Non-negative integer
The shell defines 3 by convention



stdin 0
stdout 1
stderr 2
Open


Functions defined in <unistd.h>
open function
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
Open (cont)

Required Flags




O_RDONLY
O_WRONLY
O_RDWR
Useful Optional Flags




O_APPEND
O_CREAT
O_EXCL (used with O_CREAT to cause the open
function to fail if file already exists)
O_TRUNC
Open Example
int fd;
fd = open(“data.txt”, O_RDONLY |
O_CREAT | O_TRUNC, mode);
if(fd < 0) {
perror(“Unable to open file”);
exit(1);
}
creat

creat function
int creat(const char *pathname, mode_t mode);

Same as using open with O_WRONLY |
O_CREAT | O_TRUNC, mode)
close



close function
int close(int fd);
Returns 0 on success or -1 on error
Kernel will close any file descriptors left
open by a process when it exits
lseek

lseek function
off_t lseek(int fildes, off_t offset, int whence);


Returns current file offset if sucessful,
otherwise -1
whence



SEEK_SET – Sets offset from beginning of file
SEEK_CUR – Relative offset from current position
SEEK_END – Sets offset past end of file
Unbuffered I/O - read



read function
ssize_t read(int fd, void *buf, size_t count);
Reads count bytes from the file
indicated by the file descriptor fd into
the buffer pointed to by buf
Returns -1 on error, 0 on end of file and
number of bytes read otherwise (may
be less that the number requested)
Unbuffered I/O - write

write function
ssize_t write(int fd, const void *buf, size_t count);


Attempts to write out count bytes from
buffer buf to file indicated by file
descriptor fd.
Returns -1 on error, number of bytes
written otherwise
Buffer Size and Efficiency


Program in Fig 3.4 page 69
Table in Fig 3.5 page 70
File Sharing


Multiple processes can access a file
simultaneously
3 Kernel level data structures are used
to keep track of file information




Process table
File table
v-node
See Fig 3.6 and 3.7 on pages 72, 73
Atomic Operations

Appending to a file



Separate lseek and write operations can
result in race conditions
Open file with O_APPEND to force an
atomic seek to end of file before each write
Creating a file


Separate check for file existence and
creation can result in race condition
Use both the O_CREAT and O_EXCL flags
dup and dup2


Both are functions for duplicating a file
descriptor within a process and return -1 on
error
dup



int dup(int oldfd);
Returns a new fd that points to the same entry in
the file table
dup2


int dup2(int oldfd, int newfd);
Returns newfd which now points to the same
entry in the file table as oldfd
fcntl



Allows us to change properties of an
already opened file
Several uses. See page 78 for more info
All return -1 on error, but meaning of
other return types depends on specific
use
ioctl


int ioctl(int d, int request, ...);
Catchall for I/O functions that don’t fit
well in other headers.