- int rc;
-
- if (wr)
- rc = write(fd, buf, size);
- else
- rc = read(fd, buf, size);
-
- if ((rc < 0) && (errno == -EAGAIN)) {
- fd_set set;
- struct timeval timeout;
-
- timeout.tv_sec = opt.o_report_int;
-
- FD_ZERO(&set);
- FD_SET(fd, &set);
- if (wr)
- rc = select(FD_SETSIZE, NULL, &set, NULL, &timeout);
- else
- rc = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
- if (rc < 0)
- return -errno;
- if (rc == 0)
- /* Timed out, we read nothing */
- return -EAGAIN;
-
- /* Should be available now */
- if (wr)
- rc = write(fd, buf, size);
- else
- rc = read(fd, buf, size);
- }
-
- if (rc < 0)
- rc = -errno;
-
- return rc;
+ static unsigned long long tot_bytes;
+ static time_t start_time;
+ static time_t last_time;
+ time_t now = time(0);
+ double tot_time;
+ double excess;
+ unsigned int sleep_time;
+
+ if (now > last_time + 5) {
+ tot_bytes = 0;
+ start_time = last_time = now;
+ }
+
+ tot_bytes += wsize;
+ tot_time = now - start_time;
+ if (tot_time < 1)
+ tot_time = 1;
+
+ excess = tot_bytes - tot_time * opt.o_bandwidth;
+ sleep_time = excess * 1000000 / opt.o_bandwidth;
+ if ((now - start_time) % 10 == 1)
+ CT_TRACE("bandwith control: excess=%E sleep for %dus", excess,
+ sleep_time);
+
+ if (excess > 0)
+ usleep(sleep_time);
+
+ last_time = now;