gremlin/gremlin.in: Use `locale.getpreferredencoding'.
[autoys] / flaccrip / cat-prefix
CommitLineData
583b7e4a
MW
1#! /usr/bin/tcc -run
2/* -*-c-*- */
3
4/* Some of the scripts in the `flaccrip' suite want to chop streams of PCM
5 * data about. Once upon a time, they used dd(1) for this, but dd does
6 * entirely the wrong thing on short reads, and short reads happen quite
7 * regularly on pipes.
8 *
9 * The requirements on this program are that it copy exactly the first N
10 * bytes from stdin to stdout, without reading anything else from stdin or
11 * writing anything else to stdout. (That's why it doesn't use stdio to do
12 * the copying: stdio buffering will read too much from stdin, which will
13 * cause stream corruption later.)
14 *
15 * As a special bonus, it's quite paranoid about error checking, and does way
16 * more work on dealing with short reads and writes than is necessary for
17 * working on pipes. It will fail miserably if either stdin or stdout is
18 * non-blocking.
19 */
20
21#include <errno.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <sys/types.h>
27#include <unistd.h>
28
29int main(int argc, char *argv[])
30{
31 unsigned long n;
32 size_t nn, nleft;
33 ssize_t sz;
34 char buf[40960], *p;
35
36 if (argc != 2) {
37 fprintf(stderr, "Usage: %s LENGTH\n", argv[0]);
38 exit(1);
39 }
40 n = strtoul(argv[1], 0, 0);
41
42 while (n) {
43 nn = nleft = n > sizeof(buf) ? sizeof(buf) : n;
44 p = buf;
45 while (nleft) {
46 sz = read(STDIN_FILENO, p, nleft);
47 if (sz < 0) {
48 if (errno == EINTR)
49 continue;
50 fprintf(stderr, "%s: read error: %s", argv[0], strerror(errno));
51 exit(1);
52 } else if (!sz) {
53 fprintf(stderr, "%s: unexpected eof", argv[0]);
54 exit(1);
55 }
56 nleft -= sz; p += sz;
57 }
58
59 nleft = nn;
60 p = buf;
61 while (nleft) {
62 sz = write(STDOUT_FILENO, p, nleft);
63 if (sz < 0) {
64 if (errno == EINTR)
65 continue;
66 fprintf(stderr, "%s: write error: %s", argv[0], strerror(errno));
67 exit(1);
68 } else if (!sz) {
69 fprintf(stderr, "%s: empty write", argv[0]);
70 exit(1);
71 }
72 nleft -= sz; p += sz;
73 }
74
75 n -= nn;
76 }
77 return (0);
78}