Commit | Line | Data |
---|---|---|
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 | ||
29 | int 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 | } |