Linux Programming Basics
In lieu of using lseek(), Linux provides two variants of the read() and write() system
calls. Both receive the file position from which to read or write. Upon completion, they
do not update the file position.
The read form is called pread():#define _XOPEN_SOURCE 500
#include <unistd.h>ssize_t pread (int fd, void *buf, size_t count, off_t pos);This call reads up to count bytes into buf from the file descriptor fd at file position pos.
The write form is called pwrite():#define _XOPEN_SOURCE 500
#include <unistd.h>ssize_t pwrite (int fd, const void *buf, size_t count, off_t pos);This call writes up to count bytes from buf to the file descriptor fd at file position pos.
These calls are almost identical in behavior to their non-p brethren, except that they
completely ignore the current file position; instead of using the current position, they
use the value provided by pos. Also, when done, they do not update the file position. In
other words, any intermixed read() and write() calls could potentially corrupt the
work done by the positional calls.
Both positional calls can be used only on seekable file descriptors, which include regular
files. They provide semantics similar to preceding a read() or write() call with a call
to lseek(), with three differences. First, these calls are easier to use, especially when
doing a tricky operation such as moving through a file backward or randomly. Second,
they do not update the file pointer upon completion. Finally, and most importantly, they
avoid any potential races that might occur when using lseek().
Because threads share file tables and the current file position is stored in the shared file
table, it is possible for one thread in a program to update the file position after a different
thread’s call to lseek() but before its read or write operation executed. In other words,lseek() is inherently racy when you have two or more threads in a process all manip‐
ulating the same file descriptor. Such race conditions can be avoided by using thepread() and pwrite() system calls.
calls. Both receive the file position from which to read or write. Upon completion, they
do not update the file position.
The read form is called pread():#define _XOPEN_SOURCE 500
#include <unistd.h>ssize_t pread (int fd, void *buf, size_t count, off_t pos);This call reads up to count bytes into buf from the file descriptor fd at file position pos.
The write form is called pwrite():#define _XOPEN_SOURCE 500
#include <unistd.h>ssize_t pwrite (int fd, const void *buf, size_t count, off_t pos);This call writes up to count bytes from buf to the file descriptor fd at file position pos.
These calls are almost identical in behavior to their non-p brethren, except that they
completely ignore the current file position; instead of using the current position, they
use the value provided by pos. Also, when done, they do not update the file position. In
other words, any intermixed read() and write() calls could potentially corrupt the
work done by the positional calls.
Both positional calls can be used only on seekable file descriptors, which include regular
files. They provide semantics similar to preceding a read() or write() call with a call
to lseek(), with three differences. First, these calls are easier to use, especially when
doing a tricky operation such as moving through a file backward or randomly. Second,
they do not update the file pointer upon completion. Finally, and most importantly, they
avoid any potential races that might occur when using lseek().
Because threads share file tables and the current file position is stored in the shared file
table, it is possible for one thread in a program to update the file position after a different
thread’s call to lseek() but before its read or write operation executed. In other words,lseek() is inherently racy when you have two or more threads in a process all manip‐
ulating the same file descriptor. Such race conditions can be avoided by using thepread() and pwrite() system calls.
Comments
Post a Comment