09.1 FileIO Calls C
09.1 FileIO Calls C
●
What syscalls can we use to access files (like write())?
●
Why are there stdio functions, like fprintf(), in addition to
write()?
●
Why do writes sometimes not happen right away?
25-03-10 2
Basic I/O
System Calls
25-03-10 3
File Offset This means the offset is a number (like 42) that tells the OS:
“Start reading/writing from byte 42 in the file.”
●
File offset X
.. points
a points to
that let in the fils who e a
6
– Move it to an arbitrary position using lseek()
continu
– read() and write() automatically increments the offset:
.. subsequent calls um zet
i
i
next deta
25-03-10 4
IO Syscalls
●
5 basic system calls for file I/O
– open
-
– read -
– write -
-
– close
– fcntl - File control
-
25-03-10 5
open()
mode sits
●
open() receives 2 or 3 parameters: file permission
– int open(const char *pathname, int flags);
/ 0043 Cow-rof
to
flags: ..
●
●
Recall:
↑
– int open(const char *pathname, int flags);
●
mode
– .. Sets the file permission when creating file
(flags O_CREAT or O_TMPFILE)
●
S_IRWXU: User can read/write/execute
●
S_IRUSR | S_IWUSR: .. User can read/write
●
Return Value a hanelle is just an
– .. File descriptor
:
abstraction or
reference
a handle for the file to read and write: to a resource him a
25-03-10 Imagine going to a cloakroom and giving them your jacket. They give you a token (handle). 7
That token doesn’t hold the jacket — it’s just a reference that lets you ask for your jacket later.
Common reserved FDs:
• Handle (FD) = token that lets you access and manipulate it • 2: Standard error (stderr)
descripts
filte
to an
file
write()
M
ofn to a buffer
comp array
- to store
●
call interrupted by a signal handler
– Writing takes place at the file offset, and
offset is incremented by the number of bytes actually written.
&
So will It sends the data from memory (buf) to the file/device identified by fd.
25-03-10 8
reading pipe/terminal)
●
-
-or read() was interrupted by a signal
25-03-10 9
read 1) -
It fills your buffer (buf) with data from the file/device linked to fd.
close()
it can be
releases it so
int close(int fd); - resed
- closes the file descriptor.
–
25-03-10 10
lseek() How many
lyte
to move
From where
to move
- -
off_t lseek(int fd, off_t offset, int whence);
●
Manually adjust the file offset.
– man lseek
●
whence to adjust the
which location he was
– .. from
fil offset
●
SEEK_SET: Start of file
●
SEEK_CUR: Current offset
●
SEEK_END: End of file (1st byte after end of file)
– offset is always added.
– Can seek past end of file:
next write will extend file with 0’s.
25-03-10 11
ABCD: lseek
●
Suppose a file has 6 bytes (i.e., EOF is at 6) and
the current file offset is 4: in ~
CEOF]
Index 0 1 2 3 4 5 6 7 ...
Hello !
Content H e l l o ! <EOF> --
↑
↑
-
1
SEEKEND
SEEK -
SET
b) o
2) lseek(fd,-ISEEK_CUR,1)
-1)
-
c) !
3) lseek(fd, SEEK_END, -1)
() d) none
25-03-10 12
fcntl() file descriptor operation
code optional
argument
M - -
int fcntl(int fd, int op, ... /* arg */ );
●
File control
– man fcntl
– It can do many things, such as
●
modify flags and mode used when file was opened:
op = F_SETFL (set flag)
25-03-10 13
Activity: Files
●
Write a program that:
– Creates a new file named “tmp” in current folder
– Writes X bytes to a file
●
Write a string like “Hello World!”; your choice!
– Moves the file offset backward by X/2 bytes
– Reads and prints out from the offset to EOF
– Closes the file
25-03-10 15
Categories of File Functions
functions directly
communicies
-low level
●
Syscalls with the OS Kernel
– I/O functions that are system calls:
write(), read(), etc. (previous slides)
●
.. standard library (stdio) functions but
Y – All I/O functions that start with f: -not syscall
-
but on
night fprintf(), fscanf(), fputs(), fgets(), fput(), fget(), etc. them
wee – The same functions without f:
functions printf(), scanf(), puts(), gets(), etc.
●
What’s the difference?
– Let's look at write(), fprintf(), and printf()
25-03-10 16
write() vs fprintf()
●
write() directly sends data to the kernel,
fprintf() .. manages luffer in memory
a
to
& writes to the lupfer & occasionally fluchs write)
fels using
-
actual
– Uses write() under the hood. The
25-03-10 18
Relationship
-(in
User program has data
●
User Program
memory) to write.
User Space
Data written into
●
stdio buffer
-library’s buffer. (memory)
Kernel will
-
●
25-03-10 19
Activity: Kernel Write
●
Write a program that will:
– open() a file named tmp,
– write() a string (your choice) to tmp,
– infinite loop that calls sleep() for 30 seconds each loop.
●
Experiment
– Run it in the background
– Did it write to the file tmp. Check with cat.
(It should.)
●
When done, delete tmp from the command line.
Even though the process is still running in the background, the file was written immediately because write() is
unbuffered (it goes directly to the disk).
25-03-10 20
/
cat kernel_write.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
int fd = open("tmp", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
while (1) {
sleep(30);
}
}
~/units/05-lectures/09› cat tmp
Hello World!%
~/units/05-lectures/09› ./lib_print&
[2] 31449
~/units/05-lectures/09› cat lib_print.c
#include <stdio.h>
#include <unistd.h>
int main() {
FILE *fp = fopen("tmp", "w");
// fclose(fp); I rnabled
Y
see
while (1) { we can
sleep(30);
} meg on
return 0; imp
}
~/units/05-lectures/09› cat tmp
~/units/05-lectures/09›
Activity: Library print
●
Write another program that will
– fopen() a file named tmp,
– fprintf() a string to tmp,
– infinite loop that calls sleep() for 30 seconds each iteration.
●
Run It
– Run it in the background
– Did it write to the file tmp. Check with cat.
(It should not!)
Even though the process is still running in the background, the file
was written immediately because write() is unbuffered (it goes
directly to the disk).
●
Experiment
– Change to close file after writing. Repeat running it.
It should write to file.
ver
ffluch) or fulose 1)
25-03-10 21
Standard library I/O is buffered. Always flush or close to ensure data is saved.
Buffering
●
Explain Behaviour
– Why did fprintf() not write to the file when the file is left open?
– Why did it write when we closed?
– Answer:.. Changes were differed
●
fflush() immediately sends the buffered data to the kernel.
– Calling setbuf() with NULL as the buffer automatically does
flushing.--
Y
-
25-03-10 22
Activity: fflush()
●
Change Previous Program with fprintf():
– Add fflush() call after printing
●
Run it and see if it writes to tmp. (It should.)
25-03-10 23
Kernel Buffering
User Program
●
Kernel has
read/write buffers
-
-
fprintf() fscanf() ... stdlib
too.
User Space
functions
-
[
●
Even kernel does stdio buffer
not immediately (memory)
write to disk.
Disk
25-03-10 24
Kernel Buffering
●
Can force kernel to flush buffer with*
fsync()
–
-
-
Using O_SYNC when with open() automatically does fsync().
●
Parallel between user buffering and kernel buffering
–
-
fflush() and fsync(): both flush their buffer.
– setbuf() with a NULL buffer and O_SYNC:
.. both
automatically perform
buffering
no
.
25-03-10 25
Blocking vs Non-Blocking I/O
●
Blocking call
.. doesn't return until the operation can be done .
– E.g., a blocking read() call doesn't return until there's
something to read.
●
Non-blocking call
– O_NONBLOCK flag
(either with open() or with fcntl() & F_SETFL)
– If an operation can't be done immediately, then
.. the all returns error an , typically
EAGAIN .
25-03-10 26
Imagine calling someone and waiting for them to answer — you’re blocked until they pick up. >
-
Blocking
Non-Blocking
You knock once and walk away if there’s no answer — no waiting.
>
-
Summary
●
5 Syscalls for File Access
– int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
– ssize_t write(int fd, const void *buf, size_t count);
– ssize_t read(int fd, void *buf, size_t count);
– int close();
– off_t lseek(int fd, off_t offset, int whence);
●
Syscalls vs Library functions
– write() vs fprintf()
– Non-buffered vs buffered IO
– File descriptor (int) vs stream (FILE*)
25-03-10 27