Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 21.5 Source Code 805


95 /*
96 * "Timed" read - timout specifies the # of seconds to wait before
97 * giving up (5th argument to select controls how long to wait for
98 * data to be readable). Returns # of bytes read or -1 on error.
99 *
100 * LOCKING: none.
101 */
102 ssize_t
103 tread(int fd, void *buf, size_t nbytes, unsigned int timout)
104 {
105 int nfds;
106 fd_set readfds;
107 struct timeval tv;
108 tv.tv_sec=timout;
109 tv.tv_usec=0;
110 FD_ZERO(&readfds);
111 FD_SET(fd, &readfds);
112 nfds=select(fd+1, &readfds, NULL, NULL, &tv);
113 if (nfds <= 0) {
114 if (nfds == 0)
115 errno=ETIME;
116 return(-1);
117 }
118 return(read(fd, buf, nbytes));
119 }

[95 – 107] We provide a function calledtreadto read a specified number of bytes, but
block for at mosttimoutseconds beforegiving up. This function is useful
when reading from a socket or a pipe. If we don’t receive data beforethe
specified time limit, we return−1with errnoset toETIME.Ifdata is
available within the time limit, we return at mostnbytesbytes of data, but we
can return less than requested if all the data doesn’t arrive in time.
We usetreadto prevent denial-of-service attacks on the printer spooling
daemon. A malicious user might repeatedly try to connect to the daemon
without sending it data, just to prevent other users from being able to submit
print jobs. By giving up after a reasonable amount of time, we prevent this
from happening. The tricky part is selecting a suitable timeout value that is
large enough to prevent prematurefailures when the system is under load
and tasks aretaking longer to complete. If we choose a value that is too
large, however, we might enable denial-of-service attacks by allowing the
daemon to consume too many resources to process the pending requests.
[108 – 119] Weuseselectto wait for the specified file descriptor to be readable. If the
time limit expires beforedata is available to be read,selectreturns 0, so
we seterrnotoETIMEin this case. Ifselectfails or times out, we return
−1. Otherwise, we return whatever data is available.
Free download pdf