Scattered Reading and Writing

There are times when the read(2) and write(2) calls are not convenient. This happens frequently with socket programming, where data is scattered around in different buffers. To address this issue, the UNIX kernel provides scatter read and write functions.

The readv(2) and writev(2) Functions

readv(2) and writev(2) are known as the scatter read and write functions. This is because they can read and write a number of scattered I/O buffers. The function synopsis is as follows:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

struct iovec {
    char    *iov_base;  /* Base address. */
    size_t  iov_len;    /* Length. */
} ;

In addition to the file descriptor, these functions accept two other arguments:

  • The I/O vector pointer iov

  • The count of I/O vector items iovcnt

The argument iov is actually an array of type struct iovec. Each array entry points to one buffer (by iov_base) of a specific size (size iov_len). The count iovcnt indicates how many array elements the function call should use.

The return values are otherwise identical to the read(2) and write(2) calls. The number of bytes read or written is returned. If an error occurs, -1 is returned (with errno).

Listing 4.5 shows a simple example of using writev(2). It simply writes from three separate buffers to the standard output.

Code Listing 4.5. writev.c—An Example of a writev(2) Call
1:   /* writev.c */
2:
3:   #include <stdio.h>
4:   #include <fcntl.h>
5:   #include <unistd.h>
6:   #include <errno.h>
7:   #include <string.h>
8:   #include <sys/types.h>
9:   #include <sys/uio.h>
10:
11:  int
12:  main(int argc,char **argv) {
13:      int z;                              /* Return status code */
14:      static char buf1[] = "by writev(2)";/* Middle buffer */
15:      static char buf2[] =">>>";         /* Last buffer */
16:      static char buf3[] = "<<<";         /* First buffer */
17:      static char buf4[] = "
";          /* Newline at end */
18:      struct iovec iov[4];                /* Handles 4 buffers */
19:
20:      iov[0].iov_base = buf3;
21:      iov[0].iov_len = strlen(buf3);
22:      iov[1].iov_base = buf1;
23:      iov[1].iov_len = strlen(buf1);
24:      iov[2].iov_base = buf2;
25:      iov[2].iov_len = strlen(buf2);
26:      iov[3].iov_base = buf4;
27:      iov[3].iov_len = strlen(buf4);
28:
29:      z = writev(1,&iov[0],4);            /* scatter write 4 buffers */
30:      if ( z == -1 )
31:          abort();                        /* Failed */
32:
33:      return 0;
34:  }

The session for compiling and running this program is shown next:

$ make writev
cc -c -D_POSIX_C_SOURCE=199309L -Wall writev.c
cc writev.o -o writev
$ ./writev
<<<by writev(2)>>>
$

When the program ./writev is invoked, the standard output shows the result of four buffers being combined, including the trailing ' ' character that was written.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.192.3