pump.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* pump - copy through circular buffer */
  2. #include <u.h>
  3. #include <libc.h>
  4. uchar* buf;
  5. ulong nin;
  6. ulong nout;
  7. ulong kilo;
  8. ulong max;
  9. long ssize;
  10. long tsize;
  11. int dsize;
  12. int done;
  13. int ibsize;
  14. int obsize;
  15. int verb;
  16. void doinput(int);
  17. void dooutput(int);
  18. static void
  19. usage(void)
  20. {
  21. fprint(2, "usage: pump [-f ofile] [-k KB-buffer] [-i ireadsize]\n"
  22. "\t[-o owritesize] [-b iando] [-s start-KB] [-d sleeptime] "
  23. "[files]\n");
  24. exits("usage");
  25. }
  26. void
  27. main(int argc, char *argv[])
  28. {
  29. int i, f, fo;
  30. char *file;
  31. kilo = 5000;
  32. obsize = ibsize = 8*1024;
  33. dsize = 0;
  34. fo = 1;
  35. ARGBEGIN {
  36. default:
  37. usage();
  38. case 'b':
  39. obsize = ibsize = atoi(EARGF(usage()));
  40. break;
  41. case 'd':
  42. dsize = atoi(EARGF(usage()));
  43. break;
  44. case 'f':
  45. file = EARGF(usage());
  46. fo = create(file, 1, 0666);
  47. if(fo < 0)
  48. sysfatal("can't create %s: %r", file);
  49. break;
  50. case 'i':
  51. ibsize = atoi(EARGF(usage()));
  52. break;
  53. case 'k':
  54. kilo = atoi(EARGF(usage()));
  55. break;
  56. case 'o':
  57. obsize = atoi(EARGF(usage()));
  58. break;
  59. case 's':
  60. ssize = atoi(EARGF(usage()));
  61. if(ssize <= 0)
  62. ssize = 800;
  63. ssize <<= 10;
  64. break;
  65. case 't':
  66. tsize = atol(EARGF(usage()));
  67. tsize *= 10584000; /* minutes */
  68. break;
  69. } ARGEND
  70. kilo <<= 10;
  71. buf = malloc(kilo);
  72. if(buf == nil)
  73. sysfatal("no memory: %r");
  74. nin = 0;
  75. nout = 0;
  76. done = 0;
  77. max = 0;
  78. switch(rfork(RFPROC|RFNOWAIT|RFNAMEG|RFMEM)) {
  79. default:
  80. dooutput(fo);
  81. break;
  82. case 0:
  83. for(i=0; i<argc; i++) {
  84. f = open(argv[i], OREAD);
  85. if(f < 0) {
  86. fprint(2, "%s: can't open %s: %r\n",
  87. argv0, argv[i]);
  88. break;
  89. }
  90. doinput(f);
  91. close(f);
  92. }
  93. if(argc == 0)
  94. doinput(0);
  95. break;
  96. case -1:
  97. fprint(2, "%s: fork failed: %r\n", argv0);
  98. break;
  99. }
  100. done = 1;
  101. exits(0);
  102. }
  103. void
  104. dooutput(int f)
  105. {
  106. long n, l, c;
  107. for (;;) {
  108. n = nin - nout;
  109. if(n == 0) {
  110. if(done)
  111. break;
  112. sleep(dsize);
  113. continue;
  114. }
  115. if(verb && n > max) {
  116. fprint(2, "n = %ld\n", n);
  117. max = n;
  118. }
  119. l = nout % kilo;
  120. if(kilo-l < n)
  121. n = kilo-l;
  122. if(n > obsize)
  123. n = obsize;
  124. c = write(f, buf+l, n);
  125. if(c != n) {
  126. fprint(2, "%s: write error: %r\n", argv0);
  127. break;
  128. }
  129. nout += c;
  130. if(tsize && nout > tsize) {
  131. fprint(2, "%s: time limit exceeded\n", argv0);
  132. break;
  133. }
  134. }
  135. }
  136. void
  137. doinput(int f)
  138. {
  139. long n, l, c, xnin;
  140. if(ssize > 0) {
  141. for (xnin = 0; xnin < ssize && !done; xnin += c) {
  142. n = kilo - (xnin - nout);
  143. if(n == 0)
  144. break;
  145. l = xnin % kilo;
  146. if(kilo-l < n)
  147. n = kilo-l;
  148. if(n > ibsize)
  149. n = ibsize;
  150. c = read(f, buf+l, n);
  151. if(c <= 0) {
  152. if(c < 0)
  153. fprint(2, "%s: read error: %r\n", argv0);
  154. break;
  155. }
  156. }
  157. nin = xnin;
  158. }
  159. while(!done) {
  160. n = kilo - (nin - nout);
  161. if(n == 0) {
  162. sleep(0);
  163. continue;
  164. }
  165. l = nin % kilo;
  166. if(kilo-l < n)
  167. n = kilo-l;
  168. if(n > ibsize)
  169. n = ibsize;
  170. c = read(f, buf+l, n);
  171. if(c <= 0) {
  172. if(c < 0)
  173. fprint(2, "%s: read error: %r\n", argv0);
  174. break;
  175. }
  176. nin += c;
  177. }
  178. }