#include <stdio.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <poll.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> static int pipe_fds[2]; static void print_rate(int sig) { char foo = 0; write(pipe_fds[1], &foo, sizeof(foo)); } int main(int argc, char **argv) { struct itimerval itv; struct sigaction sa; struct pollfd pollfds[2]; unsigned int count; int fd, ret; if (argc > 1) { ret = open(argv[1], O_RDONLY); if (ret < 0) { perror("open"); return ret; } fd = ret; } else fd = 0; /* STDIN */ ret = pipe(pipe_fds); if (ret < 0) { perror("pipe"); return ret; } sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = print_rate; ret = sigaction(SIGALRM, &sa, NULL); if (ret < 0) { perror("sigaction"); return ret; } itv.it_value.tv_sec = 1; itv.it_value.tv_usec = 0; itv.it_interval.tv_sec = 1; itv.it_interval.tv_usec = 0; ret = setitimer(ITIMER_REAL, &itv, 0); if (ret < 0) { perror("setitimer"); return ret; } for (;;) { char buf[256]; pollfds[0].fd = fd; pollfds[0].events = POLLIN; pollfds[0].revents = 0; pollfds[1].fd = pipe_fds[0]; pollfds[1].events = POLLIN; pollfds[1].revents = 0; ret = poll(pollfds, 2, 0); if (ret < 0) { if (errno == EAGAIN || errno == EINTR) continue; break; } if (pollfds[0].revents & POLLIN) { ret = read(fd, buf, sizeof(buf)); if (ret >= 0) count += ret; else break; } if (pollfds[1].revents & POLLIN) { read(pipe_fds[0], buf, 1); printf("Rate: %u bytes/s\n", count); count = 0; } } return ret; }