c - C语言中如何区分以下两种情况

标签 c unix

我目前正在开发一个cat程序,必须区分以下情况:

./cat 

  ./cat  < file1 > file2.txt

这是代码

  while((fileFD=read(STDIN_FILENO,str,1000))!=0)// If we just execute the command cat, it will receive input from the stdin and put it in the stdout.
   {
     write(STDOUT_FILENO,str,fileFD);// Write it to the standard output
     if(fileFD==-1)
     {
     perror("error");
     exit(1);
     }
   }
     break;    

我使用参数 argv 和 argc 来跟踪参数。在这两种情况下 argc =1 因为 < 右侧的任何内容都不会被考虑在内。你会怎么做?

最佳答案

给定两个文件描述符,一个用于输入,一个用于输出,以下函数将数据从输入相当可靠地复制到输出。

#include <unistd.h>

/* Copy file from input file descriptor ifd to output file descriptor ofd */
extern int copy_file(int ifd, int ofd);

int copy_file(int ifd, int ofd)
{
    char buffer[65536];   // Resize to suit your requirements
    ssize_t i_bytes;
    while ((i_bytes = read(ifd, buffer, sizeof(buffer))) > 0)
    {
        ssize_t bytes_left = i_bytes;
        char *posn = buffer;
        ssize_t o_bytes;
        while ((o_bytes = write(ofd, posn, bytes_left)) > 0)
        {
            bytes_left -= o_bytes;
            posn += o_bytes;
        }
        if (o_bytes < 0)
            return -1;
    }
    if (i_bytes < 0)
        return -1;
    return 0;
}

一个最基本的测试程序可能是:

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

…declaration or definition of file_copy()…

int main(void)
{
    int rc = EXIT_SUCCESS;
    if (copy_file(STDIN_FILENO, STDOUT_FILENO) != 0)
    {
        int errnum = errno;
        rc = EXIT_FAILURE;
        fprintf(stderr, "copy_file failed: (%d) %s\n", errnum, strerror(errnum));
    }
    return rc;
}

这可以正确地将文件从标准输入复制到标准输出。我还没有明确测试过“短写”。这是一种非常罕见的情况,最有可能的上下文是输出文件描述符是套接字时。测试错误路径也更加困难。我将该程序命名为 cf89。一项测试是:

$ (trap '' 13; ./cf89 < /dev/zero) | (sleep 1)
copy_file failed: (32) Broken pipe
$

trap 忽略 SIGPIPE (13),因此写入会阻塞,因为没有任何内容正在读取管道。当 sleep 退出时,写入过程会从 write() 收到错误 - 因为信号被忽略 - 并生成错误消息。

顺便说一句,有些人出于安全原因反对同时报告错误号和错误消息 - 如果攻击者设法触发错误,这会告诉攻击者太多有关系统的信息。我不属于那个阵营;攻击者在攻击此类程序时已经知道系统类型。它可能与其他上下文相关,例如 Web 服务器。

关于c - C语言中如何区分以下两种情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43303710/

相关文章:

c - 了解用于处理文件描述符的linux内核数据结构

c - c 语言编程取决于操作系统

linux - 如何从 UNIX 中的文件中删除单词?

c - 局部静态和局部变量的内存分配

c - 用 0 初始化整数与不在 C 中初始化它

c# - Objective C 前端 - Java/C# 后端

c - 为什么我们不能在某些进程上接受()套接字并从其子进程中接收()数据?

c - 了解 unix sys/select.h 中的 fd_set

php - 自动显示 public_html 文件夹

c - INT_MAX 和 INT_MAX 之和