60-256 System Programming: Unix file Input/Output
Content
COMP-2560 System Programming
Unix file Input/Output (System i/o)
Courtesy of Dr. B. Boufama
Modified by Dan Wu
School of Computer Science University of Windsor
Instructor: Dr. Dan Wu
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Content
Content
1
Unix I/O system calls
2
open()/close() system call
3
read() and write() system calls
4
lseek() system call
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Unix I/O system calls
Unix I/O system calls
Most Unix I/O can be performed using the system calls:
open: to open a file
Create?: to create a new file or rewrite an existing one
read: to read a number of bytes
write: to write a number of bytes
lseek: to explicitly position the file offset close: to close a file
In contrast to the standard I/O functions, the Unix I/O system calls are unbuffered (what doe it mean?).
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
File descriptors
The kernel refers to any open file by a file descriptor, a nonnegative integers.
File descriptors range from 0 through OPEN MAX, the total number of files a process can open.
The standard input (stdin), standard output (stdout) and standard error (stderr) have descriptors 0, 1 and 2 respectively.
The symbolic constants, defined in
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
File descriptors
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
open() system call
open() synopsis
int open(const char *fName, int oflag[, int mode])
Returns file descriptor if OK, -1 otherwise.
The argument oflag is formed by bitwise OR’ing together 1 or more of the following constants (in < fcntl.h >)
O RDONLY : Open for reading only
O WRONLY : Open for writing only
O RDWR : Open for reading and writing only
O APPEND : Open for writing after the end of file
O CREAT : Create a file
O_EXCL: do your research in lab 1
……
Note that the third argument, only used when a file is created, supplies the initial file’s permission flag settings, as an octal value.
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Examples
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Examples
if ((d=open(‘‘data.txt’’, O RDONLY))==-1) fatalError();
d=open(name,O CREAT|O WRONLY,0700) In this case,
0700 means give all rights to the owner of this file and no permission to any other user.
Example values for mode :
0400: Allow read by owner 0200: Allow write by owner 0100: Allow execute
0040: Allow read by group 0004: Allow read by others
0777: Allow read/write/execute by all
Unix file Input/Output
XXX XXX XXX:
we discussed this in class, ie.file permission for self, group, others
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Examples
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Examples
Unix file Input/Output
if open() succeeds, it is guaranteed to use the lowest-numbered
unused file descriptor for the process.
We can use this feature to ensure that a file is opened using a particular file descriptor.
For example, the following sequence
ensures that a file is opened using standard input (file descriptor 0).
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
read() and write() system calls
read() synopsis
ssize t read(int fd, void *buf, size t nbyte); Reads as many bytes as it can, up to nbyte, and returns the number of bytes actually read.
ssize t and size t are usually defined as long integer(larger than an integer).
The value returned by read() can be:
-1: in case of an error
smaller than nbyte: the number of bytes left before the end of file was less than nbyte or, when reading from a keyboard where up to a line is normally read or, when reading from a network.
0: the end of file has been already reached
write() synopsis
ssize t write(int fd, const void *buf, size t nbyte);
write returns nbyte if OK and -1 otherwise.
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Example of a copy utility (copy.c)
#include
int main(int argc, char *argv[]){ int fd1, fd2;
char buffer[100]; long int n1;
if(((fd1 = open(argv[1], O_RDONLY)) == -1) || ((fd2 = open(argv[2], O_CREAT|O_WRONLY|O_TRUNC,
0700)) == -1)){
perror(“file problem “); exit(1);
}
while((n1=read(fd1, buffer, 100)) > 0) if(write(fd2, buffer, n1) != n1){
perror(“writing problem “); exit(3);
}
// Case of an error exit from the loop if(n1 == -1){
perror(“Reading problem “); exit(2);
}
Close(fd1);
close(fd2); exit(0);
}
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
int close(int fd)
int close(int fd) frees the file descriptor fd.
If no other file descriptor is associated with a particular open file, the kernel frees all resources that were used for that file.
close() returns 0 when OK and -1 otherwise.
For example, -1 will be returned if fd was already closed.
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
lseek() system call
lseek() synopsis
off t lseek(int fd, off t offset, int whence);
Return the resulting offset if OK, -1 otherwise. The return type off t is a long integer.
Similar to fseek(), it sets the file pointer(position) associated with the open file descriptor specified by the file descriptor fd as follows:
If whence is SEEK SET, the pointer is set to offset bytes. If whence is SEEK CUR, the pointer is set to its current location plus offset.
If whence is SEEK END, the pointer is set to the size of the file plus offset.
These three constant are defined in < unistd.h >.
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
…lseek()
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
…lseek()
Note
lseek() allows the file pointer to be set beyond the existing data in the file. If data are later written at this point, subsequent reads in the gap between the previous end of data and the newly written data will return bytes of value 0 until data are written into the gap.
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Example
Reversing a file
Write a C program, called reverse, to take a file as input then copies it to another file in reverse order. That is, the last byte becomes the first, the byte just just before the last one becomes the second, etc.
The program call should look like: reverse fileIn fileOut There are two solutions,
either we use lseek() on fileIn (read bytes from the end), or
we use lseek() on fileOut. (write bytes starting at the end)
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
#include
// reverse1.c
// solution 1: Start reading at the end
// Use lseek() on fileIn int main(int argc, char *argv[]){ int fd1, fd2;
char buffer; // 1 character buffer long int i=0, fileSize=0;
fd1=open(argv[1], O_RDONLY);
fd2=open(argv[2], O_CREAT|O_WRONLY|O_TRUNC, 0755);
while(read(fd1, &buffer, 1)>0) fileSize++;
while(++i <= fileSize){ lseek(fd1, -i, SEEK_END); read(fd1, &buffer, 1);
write(fd2, &buffer, 1);
}
close(fd1); close(fd2);
}
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
//reverse2.c
//solution 2: start writing at end int main(int argc, char *argv[]){
int fd1, fd2;
char buffer; // 1 character buffer long int i=0, fileSize=0;
fd1=open(argv[1], O_RDONLY);
fd2=open(argv[2], O_CREAT|O_WRONLY|O_TRUNC, 0755);
while(read(fd1, &buffer, 1)>0) fileSize++;
lseek(fd2, fileSize-1, SEEK_SET);//pointer to end
// rewind fd1!!
lseek(fd1, 0, SEEK_SET); while(++i <= fileSize){
read(fd1, &buffer, 1);
lseek(fd2, -i, SEEK_END);
write(fd2, &buffer, 1);
}
close(fd1); close(fd2);
}
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
The file’s offset can be greater than the file’s current 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.
See the example code “hole.c”
Run it and inspect its contents using od –c file.hole
lseek() again.
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved
Unix I/O system calls
open() system call
read() and write() system calls
lseek() system call
Unix/Linux provides a globally accessible integer variable which contains an error code number……
Remember to include errno.h before using it.
perror(char *) is a library routine to output error message related to errno…..
errno and perror(char *) library function
Unix file Input/Output
Copyright @ 2019, 2020, 2021 all rights reserved