Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
30 views41 pages

CSE203 LP Unit III A

The document covers file I/O operations in Linux programming, detailing the use of various flags for the open() function, including access modes and file creation options. It also explains the read() and write() system calls, error handling, and the importance of synchronized I/O with fsync() and fdatasync(). Additionally, it discusses multiplexed I/O using select(), poll, and epoll interfaces for managing multiple file descriptors efficiently.

Uploaded by

Santosh Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views41 pages

CSE203 LP Unit III A

The document covers file I/O operations in Linux programming, detailing the use of various flags for the open() function, including access modes and file creation options. It also explains the read() and write() system calls, error handling, and the importance of synchronized I/O with fsync() and fdatasync(). Additionally, it discusses multiplexed I/O using select(), poll, and epoll interfaces for managing multiple file descriptors efficiently.

Uploaded by

Santosh Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

CSE203 LINUX PROGRAMMING

UNIT – III

P. Rajendiran
AP / IT / SoC

11/15/2022 1
File I/O

Flags for open()


The flags argument is the bitwise-OR of one or more flags. It must contain an access mode,
which is one of O_RDONLY, O_WRONLY, or O_RDWR
For example, the following code opens /home/kidd/madagascar for reading:
int fd;
fd = open ("/home/kidd/madagascar", O_RDONLY);
if (fd == −1) /* error */

11/15/2022 2
File I/O
On top of the access mode, the flags argument may be
bitwise-ORed with zero or more of the following values,
modifying the behavior of the open request:
O_APPEND
The file will be opened in append mode. That is, before each
write, the file position will be updated to point to the end of
the file.
O_ASYNC
This flag is available only for FIFOs, pipes, sockets, and
terminals, not for regular files.
O_CREAT
If the file denoted by name does not exist, the kernel will
create it. If the file already exists, this flag has no effect unless
O_EXCL is also given.

11/15/2022 3
File I/O
O_TRUNC
If the file exists, it is a regular file, and the given flags allow
for writing, the file will be truncated to zero length.
int fd;
fd = open ("/home/teach/pearl", O_WRONLY | O_TRUNC);
if (fd == −1) /* error */
Permissions of New Files
The following set of constants that may be binary-ORed together and sup‐ plied for the
mode argument:

11/15/2022 4
File I/O

11/15/2022 5
File I/O

11/15/2022 6
File I/O

11/15/2022 7
11/15/2022 8
Return Values and Error Codes
Both open() and creat() return a file descriptor on
success. On error, both return −1, and set errno to an
appropriate error value
Reading via read()
#include <unistd.h>
ssize_t read (int fd, void *buf, size_t len);
Each call reads up to len bytes into the memory pointed
at by buf from the current file offset of the file
referenced by fd. On success, the number of bytes
written into buf is returned. On error, the call returns −1
and sets errno.
11/15/2022 9
Return Values
A call to read() can result in many possibilities:
-The call returns a value equal to len. All len read bytes
are stored in buf
- The call returns a value less than len, but greater than
zero. This can occur because a signal interrupted the
read midway
- The call returns 0. This indicates EOF. There is
nothing to read.
- The call blocks because no data is currently available.
-EINTR, -EAGAIN

11/15/2022 10
Reading All the Bytes
To handle all errors and actually read all len bytes (at
least up to an EOF).

11/15/2022 11
Nonblocking Reads

11/15/2022 12
Writing with write()
#include <unistd.h>
ssize_t write (int fd, const void *buf, size_t count);

11/15/2022 13
Partial Writes
The write() system call is less likely to return a partial
write than the read() system call is to return a partial
read.

11/15/2022 14
11/15/2022 15
Synchronized I/O
Buffering writes provides a significant performance
improvement, and consequently, any operating system
even halfway deserving the mark “modern” implements
delayed writes via buffers.
fsync() and fdatasync()
The simplest method of ensuring that data has reached
the disk is via the fsync() system call.
int fsync (int fd);
A call to fsync() ensures that all dirty data associated with the file mapped
by the file descriptor fd are written back to disk. The file descriptor fd
must be open for writing. The call writes back both data and metadata,
such as timestamps and other attributes contained in the inode.
11/15/2022 16
int fdatasync (int fd);
This system call does the same thing as fsync(), it only
flushes data and metadata required to properly access
the file in the future.
Both functions are used the same way, which is very
simple:
int ret;
ret = fsync (fd);
if (ret == −1)
/* error */

11/15/2022 17
or when using fdatasync()
int ret;
/* same as fsync, but won't flush non-essential metadata
*/
ret = fdatasync (fd);
if (ret == −1)
/* error */

11/15/2022 18
sync()
void sync (void);
The function has no parameters and no return value. It
always succeeds and, upon return, all buffers both data
and metadata are guaranteed to reside on disk.
The standards do not require sync() to wait until all
buffers are flushed to disk before returning; they require
only that the call initiates the process of committing all
buffers to disk.

11/15/2022 19
11/15/2022 20
O_DSYNC and O_RSYNC
O_DSYNC only normal data to be synchronised
O_RSYNC both read and write to be synchronised

Direct I/O
The Linux kernel, like any modern operating system
kernel, implements a complex layer of caching,
buffering, and I/O management between devices and
applications
A high-performance application may wish to bypass this
layer of complexity and perform its own I/O
management
11/15/2022 21
Closing Files
int close (int fd);
A call to close() unmaps the open file descriptor fd and
disassociates the file from the process.
A call to close() returns 0 on success. On error, it returns
−1 and sets errno appropriately.
Seeking with lseek()

11/15/2022 22
SEEK_CUR
The current file position of fd is set to its current value
plus pos, which can be negative, zero, or positive. A pos
of zero returns the current file position value.
SEEK_END
The current file position of fd is set to the current length
of the file plus pos, which can be negative, zero, or
positive. A pos of zero sets the offset to the end of the
file.
SEEK_SET
The current file position of fd is set to pos. A pos of zero
sets the offset to the beginning of the file.
11/15/2022 23
11/15/2022 24
11/15/2022 25
11/15/2022 26
Multiplexed I/O
 We need to understand a few concepts first:
 User and Kernel Mode
 In any modern operating system, the CPU is actually
spending time in two very distinct modes:
 In Kernel mode, the executing code has complete and
unrestricted access to the underlying hardware. It can
execute any CPU instruction and reference any
memory address. Kernel mode is generally reserved for
the lowest-level, most trusted functions of the
operating system. Crashes in kernel mode will halt the
entire PC.

11/15/2022 27
 In User mode, the executing code has no ability to
directly access hardware or reference memory. Code
running in user mode must delegate to system APIs to
access hardware or memory. Due to the protection
afforded by this sort of isolation, crashes in user mode
are always recoverable. Most of the code running on
your computer will execute in user mode.
 Process Switching - A process switch is a operating
system scheduler change from one running program to
another. This requires saving all of the state of the
currently executing program, including its register
state, associated kernel state, and all of its virtual
memory configuration.
11/15/2022 28
A process switch will through the following changes:
 Save the processor context, including program
counters and other registers
 Update the process control block (PCB) information
 Move the process of the PCB into the appropriate
queue, such as ready queue, event block queue and
other queues
 Select another process to execute and update its PCB
 Update the data structure in the memory
 Restore the PCB context

11/15/2022 29
 Blocking Processes
 A blocking process is usually waiting for an event such
as a semaphore being released or a message arriving in
its message queue.
 A process that continues to run while waiting (i.e.,
continuously polling for the event in a tight loop) is
said to be busy-waiting, which is undesirable as it
wastes clock cycles which could be used for other
processes. When the process into the blocked state, is
not occupied by CPU resources

11/15/2022 30
 Buffered I/O
 Buffered output streams will accumulate write results
into an intermediate buffer, sending it to the OS file
system only when enough data has accumulated (or
flush() is requested). This reduces the number of file
system calls
 File Descriptor (FD) In Unix and related computer
operating systems, a file descriptor (FD, less frequently
fildes) is an abstract indicator (handle) used to access
a file or other input/output resource, such as a pipe or
network socket

11/15/2022 31
 When a read operation occurs, the data goes through
two phases:
 Waiting for the data to be ready
 Copying the data from the kernel to the process
 Because these two phases, Linux system produced the
following 5 network model:
 Blocking I/O, Nonblocking I/O, I/O Multiplexing
 Signal Driven I/O (uncommonly used)
 Asynchronous I/O

11/15/2022 32
multiplexed I/O.
 Multiplexed I/O allows an application to concurrently
block on multiple file descriptors and receive
notification when any one of them becomes ready to
read or write without blocking
 Multiplexed I/O: 1. Tell me when any of these file
descriptors become ready for I/O.
 2. Nothing ready? Sleep until one or more file
descriptors are ready.
 3. Woken up! What is ready?
 4. Handle all file descriptors ready for I/O, without
blocking. 5. Go back to step 1.
11/15/2022 33
 Linux provides three multiplexed I/O solutions: the
select, poll, and epoll interfaces.
select()
 The select() system call provides a mechanism for
implementing synchronous multiplexing I/O:
 #include <sys/select.h>
 int select (int n,
 fd_set *readfds,
 fd_set *writefds,

11/15/2022 34
 fd_set *exceptfds,
 struct timeval *timeout);
 FD_CLR(int fd, fd_set *set);
 FD_ISSET(int fd, fd_set *set);
 FD_SET(int fd, fd_set *set);
 FD_ZERO(fd_set *set);
 A call to select() blocks until the given file descriptors
are ready to perform I/O, or until an optionally
specified timeout has elapsed

11/15/2022 35
 The watched file descriptors are broken into three sets,
each waiting for a different event.
 File descriptors listed in the readfds set are watched to
see if data is available for reading
 File descriptors listed in the writefds set are watched to
see if a write operation will complete without blocking.
 file descriptors in the exceptfds set are watched to see
if an exception has occurred
 The first parameter, n, is equal to the value of the
highest-valued file descriptor in any set, plus one

11/15/2022 36
 The timeout parameter is a pointer to a timeval
structure, which is defined as follows:
 #include <sys/time.h>
 struct timeval {
 long tv_sec; /* seconds */
 long tv_usec; /* microseconds */
 };

11/15/2022 37
 If this parameter is not NULL, the call to select() will
return after tv_sec seconds and tv_usec microseconds,
even if no file descriptors are ready for I/O.
 FD_ZERO removes all file descriptors from the
specified set. It should be called before every
invocation of select():
 fd_set writefds;
 FD_ZERO(&writefds);

11/15/2022 38
 FD_SET adds a file descriptor to a given set, and
FD_CLR removes a file descriptor from a given set:
 FD_SET(fd, &writefds); /* add 'fd' to the set */
 FD_CLR(fd, &writefds); /* oops, remove 'fd' from the
set */
 FD_ISSET tests whether a file descriptor is part of a
given set. It returns a nonzero integer if the file
descriptor is in the set and 0 if it is not

11/15/2022 39
Return values and error codes
 On success, select() returns the number of file
descriptors ready for I/O, among all three sets
 If a timeout was provided, the return value may be 0.
On error, the call returns −1, and errno is set to one of
the following values:

11/15/2022 40
 EBADF - An invalid file descriptor was provided in one
of the sets.
 EINTR - A signal was caught while waiting, and the
call can be reissued.
 EINVAL -The parameter n is negative, or the given
timeout is invalid.
 ENOMEM - Insufficient memory was available to
complete the request

11/15/2022 41

You might also like