#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;
}

当我用管道ex:cat test.txt| ./a.out result.txt运行程序时

但用另一种方法,例如:./a.out result.txt <test.txt

此外,当我拼接到STDOUT_FILENO时,它从未打印在标准输出上,我不明白为什么.

谢谢你的帮助

推荐答案

这两种方法并不等同:

  • cat in.txt |实际上会创建一个pipe来为你的程序提供数据
  • < in.txt只需要open个给定的文件,然后将其发送到fd 0

在第二种情况下,tee返回-1perror抱怨无效参数.

您可以使用fstat判断fd 0的性质,并判断st_mode值:

    struct stat statbuf;
    fstat(STDIN_FILENO, &statbuf);
    
    if (statbuf.st_mode & S_IFREG) 
        printf("regular file");
    
    if (statbuf.st_mode & S_IFIFO) 
        printf("pipe");

C++相关问答推荐

错误:C中需要参数声明符

无效使用未定义类型'structsquare'?

C语言中字符数组声明中的标准

两个连续的语句是否按顺序排列?

C由四个8位整数组成无符号32位整数

_泛型控制表达式涉及数组碰撞警告的L值转换错误?

Char变量如何在不使用方括号或花括号的情况下存储字符串,以及它如何迭代到下一个字符?

为什么指针运算会产生错误的结果?

如何在C中只对字符串(包含数字、单词等)中的数字进行重复操作?

cairo 剪辑区域是否存在多个矩形?

预处理器宏扩展(ISO/IEC 9899:1999(E)§;6.10.3.5示例3)

为什么这个分配做得不好呢?

C语言中浮点数的取整方式浮点数尾数超过23位时如何取整剩余部分

为什么WcrTomb只支持ASCII?

在C程序中使用Beaglebone Black UART的问题

为什么会出现此错误?二进制表达式的操作数无效

将size_t分配给off_t会产生符号转换错误

在C中打印指针本身

这些表达式是否涉及 C 中定义的复合文字?

仅使用其内存地址取消引用 C 中的 struct