The pread and pwrite system calls do atomic position-and-read or write, eliminating the necessity of using a locking mechanism when both operations are desired and file descriptors are shared. They accomplish this using a fourth argument, offset. The synopsis for these system calls are as follows:
n = pread(fildes, buffer, count), offset);
n = pwrite(fildes, buffer, count), offset);
The read or write is done as if an lseek to offset (from the beginning of the file) were done first. Note that (though the semantics are analogous) an lseek is not actually performed; the file pointer is not affected by pread or pwrite. The read or write of nbytes then starts at the specified offset.
The atomicity of pread and pwrite enable processes or threads that share file descriptors to read or write from a shared file at a particular offset without using a locking mechanism that would be necessary to achieve the same result in separate lseek and read or write system call. Atomicity is required as the file pointer is shared and one thread might move the pointer using lseek after another process completes an lseek but prior to the read or write.
On success, pread returns the number of bytes actually read and placed in buf; pwrite will return the number of bytes actually written from buf on success. A value of 0 is returned for pread when an end-of-file has been reached. On failure, pread and pwrite return -1 and set errno to identify the error.