#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <err.h>
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;
}
Comments
0 B
|👍
/👎
0 B
|👍
/👎