1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #define _GNU_SOURCE |
3 | #include <errno.h> |
4 | #include <fcntl.h> |
5 | #include <limits.h> |
6 | #include <stdio.h> |
7 | #include <stdlib.h> |
8 | #include <unistd.h> |
9 | #include <sys/types.h> |
10 | #include <sys/stat.h> |
11 | |
12 | int main(int argc, char *argv[]) |
13 | { |
14 | int fd; |
15 | size_t size; |
16 | ssize_t spliced; |
17 | |
18 | if (argc < 2) { |
19 | fprintf(stderr, "Usage: %s INPUT [BYTES]\n" , argv[0]); |
20 | return EXIT_FAILURE; |
21 | } |
22 | |
23 | fd = open(argv[1], O_RDONLY); |
24 | if (fd < 0) { |
25 | perror(argv[1]); |
26 | return EXIT_FAILURE; |
27 | } |
28 | |
29 | if (argc == 3) |
30 | size = atol(argv[2]); |
31 | else { |
32 | struct stat statbuf; |
33 | |
34 | if (fstat(fd, &statbuf) < 0) { |
35 | perror(argv[1]); |
36 | return EXIT_FAILURE; |
37 | } |
38 | |
39 | if (statbuf.st_size > INT_MAX) { |
40 | fprintf(stderr, "%s: Too big\n" , argv[1]); |
41 | return EXIT_FAILURE; |
42 | } |
43 | |
44 | size = statbuf.st_size; |
45 | } |
46 | |
47 | /* splice(2) file to stdout. */ |
48 | spliced = splice(fd, NULL, STDOUT_FILENO, NULL, |
49 | size, SPLICE_F_MOVE); |
50 | if (spliced < 0) { |
51 | perror("splice" ); |
52 | return EXIT_FAILURE; |
53 | } |
54 | |
55 | close(fd); |
56 | return EXIT_SUCCESS; |
57 | } |
58 | |