/* * buffer: try to stream data * * usage: * | buffer -i -o > output * buffer -i -o < input | #include #include #include #include #include #include int ibs = 512, obs = 512; void consumer(int childno) { static char buffer[20480]; /* tape blocksize of 40 */ int status, size, chunk; char *ptr; while (1) { if (flock(0, LOCK_EX) == -1) /* grab control of our input */ if (errno = EINTR) continue; else { kill(getppid(), SIGHUP); exit(0); } chunk = sizeof buffer; ptr = buffer; while (chunk > 0) { if ((size = read(0, ptr, chunk)) > 0) { chunk -= size; ptr += size; } else break; } while (flock(1, LOCK_EX) == -1) if (errno != EINTR) { kill(getppid(), SIGHUP); exit(0); } flock(0, LOCK_UN); /* release input to the next thread */ if (ptr > buffer) write(1, buffer, ptr-buffer); flock(1, LOCK_UN); if (ptr == buffer) { exit(0); } } } main() { int x; #define NRCHILD 16 pid_t children[NRCHILD]; pid_t child; int nrchild; for (x=0; x < NRCHILD; x++) { child = fork(); if (child == 0) { consumer(x); exit(0); } else if (child > 0) { children[x] = child; nrchild++; } else { children[x] = 0; } } if (nrchild == 0) { perror("forking consumers"); exit(1); } while (nrchild > 0) if ((child = wait(&x)) > 0) { for (x = 0; x < NRCHILD; x++) if (children[x] == child) { children[x] = 0; nrchild--; } } exit(0); }