#define _GNU_SOURCE #include #include #include #include #include #include int main(int argc, char *argv[]) { // Just a MB less than LONG_MAX size_t size = LONG_MAX - (1024 * 1024); int in, pipefd[2], r; in = open(argv[1], O_RDONLY); if (in < 0) err(1, "open"); r = pipe(pipefd); if (r < 0) err(1, "pipe"); r = fork(); if (r < 0) err(1, "fork"); if (!r) { // Discard data from pipe char *buffer = malloc(1024 * 1024); while (read(pipefd[0], buffer, 1024 * 1024) > 0) /* do nothing */ ; return 0; } // splice data from file to pipe for (ssize_t copied = 1; copied; ) { copied = splice(in, NULL, pipefd[1], NULL, size, 0); if (copied < 0) { perror("splice"); // splice() will fail when file pos + size exceeds LONG_MAX fprintf(stderr, "Failed to splice %zu bytes at offset %ld\n", size, lseek(in, 0, SEEK_CUR)); return 1; } } return 0; }