In some situations, system-level read and write functions transfer few bytes than the application requests. Such short counts do not indicate an error. They occur for a number of reasons: encountering EOF on reads, reading text lines from a terminal, reading and writing network sockets.
An I/O package called RIO (Robust I/O) package that handles these short counts automatically. Applications can transfer data directly between memory and a file by calling the rio_readn and rio_writen functions.
The rio_readn function transfers up to n bytes from the current file position of descriptor fd to memory location usrbuf. The rio_readn function can only return a short count if it encounters EOF.
ssize_t rio_readn(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nread = read(fd, bufp, nleft)) < 0) {
if (errno == EINTR) // Interrupted by signal handle return
nread = 0; // and call read() again
else
return -1; // errno set by read()
}
else if (nread == 0)
break; // EOF
nleft -= nread;
bufp += nread;
}
return (n - nleft); // Return >= 0
}
The rio_writen function transfers up to n bytes from memory location usrbuf to descriptor fd. The rio_writen function never returns a short count.
ssize_t rio_writen(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nwritten;
char *bufp = usrbuf;
while (nleft > 0) {
if ((nwritten = write(fd, bufp, nleft)) < 0) {
if (errno == EINTR) // Interrupted by signal handle return
nwritten = 0; // and call write() again
else
return -1; // errno set by write()
}
nleft -= nwritten;
bufp += nwritten;
}
return n;
}