10f66f451Sopenharmony_ci/* count.c - Progress indicator from stdin to stdout
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2002 Rob Landley <rob@landley.net>
40f66f451Sopenharmony_ci
50f66f451Sopenharmony_ciUSE_COUNT(NEWTOY(count, NULL, TOYFLAG_USR|TOYFLAG_BIN))
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ciconfig COUNT
80f66f451Sopenharmony_ci  bool "count"
90f66f451Sopenharmony_ci  default y
100f66f451Sopenharmony_ci  help
110f66f451Sopenharmony_ci    usage: count
120f66f451Sopenharmony_ci
130f66f451Sopenharmony_ci    Copy stdin to stdout, displaying simple progress indicator to stderr.
140f66f451Sopenharmony_ci*/
150f66f451Sopenharmony_ci
160f66f451Sopenharmony_ci#include "toys.h"
170f66f451Sopenharmony_ci
180f66f451Sopenharmony_civoid count_main(void)
190f66f451Sopenharmony_ci{
200f66f451Sopenharmony_ci  struct pollfd pfd = {0, POLLIN, 0};
210f66f451Sopenharmony_ci  unsigned long long size = 0, last = 0, then = 0, now;
220f66f451Sopenharmony_ci  char *buf = xmalloc(65536);
230f66f451Sopenharmony_ci  int len;
240f66f451Sopenharmony_ci
250f66f451Sopenharmony_ci  // poll, print if data not ready, update 4x/second otherwise
260f66f451Sopenharmony_ci  for (;;) {
270f66f451Sopenharmony_ci    if (!(len = poll(&pfd, 1, (last != size) ? 250 : 0))) continue;
280f66f451Sopenharmony_ci    if (len<0 && errno != EINTR && errno != ENOMEM) perror_exit(0);
290f66f451Sopenharmony_ci    if ((len = xread(0, buf, 65536))) {
300f66f451Sopenharmony_ci      xwrite(1, buf, len);
310f66f451Sopenharmony_ci      size += len;
320f66f451Sopenharmony_ci      if ((now = millitime())-then<250) continue;
330f66f451Sopenharmony_ci    }
340f66f451Sopenharmony_ci    dprintf(2, "%llu bytes\r", size);
350f66f451Sopenharmony_ci    if (!len) break;
360f66f451Sopenharmony_ci  }
370f66f451Sopenharmony_ci  dprintf(2, "\n");
380f66f451Sopenharmony_ci}
39