#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
int main(int argc, char ** argv) {
int fd[2];
int len,slen,len_out,slen_out;
pipe(fd);
int f=open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
len=tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE);
while (len > 0) {
slen = splice(fd[0], NULL, f, NULL, len, SPLICE_F_MOVE);
len -= slen;
if(slen==0)
break;
}
len_out = tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE);
while (len_out > 0) {
slen_out = splice(fd[0], NULL, STDOUT_FILENO, NULL, len_out, SPLICE_F_MOVE);
len_out -= slen_out;
if(slen_out==0)
break;
}
close(fd[1]);
close(fd[0]);
close(f);
return 0;
}
When I run my program with a pipe ex: cat test.txt| ./a.out result.txt
The content from test.txt
goes into result.txt
But with the other method, ex: ./a.out result.txt <test.txt
nothing happens. Isn't it suppose to act the same ?
Also, when I splice to the STDOUT_FILENO
, it never print on the standard output, and I do not understand why.
Thank you for your help
CodePudding user response:
The two methods are not equivalent:
cat in.txt |
will actually create apipe
to feed your program< in.txt
will justopen
the given file and serve it afd
0
On second case, tee
returns -1
, and perror
complains about an invalid argument.
You can check the nature of fd
0
using fstat
and checking the st_mode
value:
struct stat statbuf;
fstat(STDIN_FILENO, &statbuf);
if (statbuf.st_mode & S_IFREG)
printf("regular file");
if (statbuf.st_mode & S_IFIFO)
printf("pipe");