18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#define _GNU_SOURCE
38c2ecf20Sopenharmony_ci#include <errno.h>
48c2ecf20Sopenharmony_ci#include <fcntl.h>
58c2ecf20Sopenharmony_ci#include <limits.h>
68c2ecf20Sopenharmony_ci#include <stdio.h>
78c2ecf20Sopenharmony_ci#include <stdlib.h>
88c2ecf20Sopenharmony_ci#include <unistd.h>
98c2ecf20Sopenharmony_ci#include <sys/types.h>
108c2ecf20Sopenharmony_ci#include <sys/stat.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ciint main(int argc, char *argv[])
138c2ecf20Sopenharmony_ci{
148c2ecf20Sopenharmony_ci	int fd;
158c2ecf20Sopenharmony_ci	size_t size;
168c2ecf20Sopenharmony_ci	ssize_t spliced;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	if (argc < 2) {
198c2ecf20Sopenharmony_ci		fprintf(stderr, "Usage: %s INPUT [BYTES]\n", argv[0]);
208c2ecf20Sopenharmony_ci		return EXIT_FAILURE;
218c2ecf20Sopenharmony_ci	}
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	fd = open(argv[1], O_RDONLY);
248c2ecf20Sopenharmony_ci	if (fd < 0) {
258c2ecf20Sopenharmony_ci		perror(argv[1]);
268c2ecf20Sopenharmony_ci		return EXIT_FAILURE;
278c2ecf20Sopenharmony_ci	}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	if (argc == 3)
308c2ecf20Sopenharmony_ci		size = atol(argv[2]);
318c2ecf20Sopenharmony_ci	else {
328c2ecf20Sopenharmony_ci		struct stat statbuf;
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci		if (fstat(fd, &statbuf) < 0) {
358c2ecf20Sopenharmony_ci			perror(argv[1]);
368c2ecf20Sopenharmony_ci			return EXIT_FAILURE;
378c2ecf20Sopenharmony_ci		}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci		if (statbuf.st_size > INT_MAX) {
408c2ecf20Sopenharmony_ci			fprintf(stderr, "%s: Too big\n", argv[1]);
418c2ecf20Sopenharmony_ci			return EXIT_FAILURE;
428c2ecf20Sopenharmony_ci		}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci		size = statbuf.st_size;
458c2ecf20Sopenharmony_ci	}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	/* splice(2) file to stdout. */
488c2ecf20Sopenharmony_ci	spliced = splice(fd, NULL, STDOUT_FILENO, NULL,
498c2ecf20Sopenharmony_ci		      size, SPLICE_F_MOVE);
508c2ecf20Sopenharmony_ci	if (spliced < 0) {
518c2ecf20Sopenharmony_ci		perror("splice");
528c2ecf20Sopenharmony_ci		return EXIT_FAILURE;
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	close(fd);
568c2ecf20Sopenharmony_ci	return EXIT_SUCCESS;
578c2ecf20Sopenharmony_ci}
58