splice.c (1376B)
1#include <err.h> 2#include <stdio.h> 3#include <stdint.h> 4#include <stdlib.h> 5 6#define MIN(a, b) ((a) < (b) ? (a) : (b)) 7 8int 9main(int argc, const char **argv) 10{ 11 char buf[BUFSIZ]; 12 ssize_t start, end; 13 ssize_t pos, nread, nreq; 14 FILE *main_file; 15 char *endc; 16 int ret; 17 18 if (argc < 3 || argc > 4) { 19 fprintf(stderr, "USAGE: splice MAIN START [END]\n"); 20 return 0; 21 } 22 23 main_file = fopen(argv[1], "rb"); 24 if (!main_file) err(1, "fopen %s", argv[1]); 25 26 start = strtoll(argv[2], &endc, 0); 27 if (endc && *endc) err(1, "strtoll %s", argv[2]); 28 if (start < 0) errx(1, "negative start"); 29 30 if (argc == 4) { 31 end = strtoll(argv[3], &endc, 0); 32 if (endc && *endc) err(1, "strtoll %s", argv[3]); 33 if (start >= end) errx(1, "invalid end"); 34 } else { 35 end = -1; 36 } 37 38 pos = 0; 39 while (!feof(main_file) || !feof(stdin)) { 40 if (pos >= start && (pos < end || !feof(stdin))) { 41 if (feof(stdin)) errx(1, "input truncated"); 42 nreq = end >= 0 ? MIN(BUFSIZ, end - start) : BUFSIZ; 43 nread = fread(buf, 1, nreq, stdin); 44 if (pos == start && end >= 0) 45 fseek(main_file, end, SEEK_SET); 46 else if (end < 0) 47 fseek(main_file, nread, SEEK_CUR); 48 } else { 49 nreq = pos < start ? MIN(BUFSIZ, start - pos) : BUFSIZ; 50 nread = fread(buf, 1, nreq, main_file); 51 } 52 if (fwrite(buf, 1, nread, stdout) != nread) 53 errx(1, "output truncated"); 54 pos += nread; 55 } 56 57 fclose(main_file); 58}