程序读取文件,并将它与管道发送到父进程(Program that read file and sen

2019-06-23 14:30发布

我需要编写创建管从命令行发送文件名,子进程的程序。 在小时候看过该文件,并使用管道将其发回。 父进程要打印的文件。 如果发生在子过程中的错误必须将错误发送到父进程。

这里是我的代码,它沿着打印文件文件中的一些垃圾(和它的终端仿真器禁用滚动当我运行它)。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void main(int argc, char *argv[]) {
   int pipefd[2];
   char buff[100];
   int childpid;
   int size;
   FILE *file;

   if (argc != 2) {
      printf("usage:\n%s <filename>\n", argv[0]);
      exit(1);
   }
   if (pipe(pipefd) < 0) {
       perror("can't open pipe\n");
   }
   if ((childpid = fork()) == 0) {
      sleep(1);
      size = read(pipefd[0], buff, sizeof(buff));
      file = fopen(buff, "r");
      if (file == NULL) {
         write(pipefd[1], "Can't open file", 15);
         exit(1);
      }
      while (!feof(file)) {
         if (fgets(buff, sizeof(buff), file) == NULL) {
            write(pipefd[1], "Error reading file", 18);
         } else {
            write(pipefd[1], buff, sizeof(buff));
         }
      }
   } else if (childpid > 0) {
      size = strlen(argv[1]);
      if (write(pipefd[1], argv[1], size) != size) {
         perror("Error writing to pipe\n");
      }
      wait(NULL);
      while ((size = read(pipefd[0], buff, sizeof(buff))) > 0) {
         write(1, buff, size);
      }
   }
   exit(0);
}

Answer 1:

相当多的变化后,如预期你的程序工作。 让名单出来需要什么样的所有变化和为什么 -

I)无论是在儿童和家长,一旦关闭相应的管道,你与他们所做的。 从手册页的read(3)

如果某些进程打开了写作的管道和O_NONBLOCK清晰,阅读(),直到一些数据被写入或关闭管道时通过了对写开放钢管全部过程必须阻止调用线程。

所以,做这样的事情在你的代码到处在作业的管道已经结束,

  size = read(pipefd[0], buff, sizeof(buff));
  close(pipefd[0]);

  write(pipefd[1], buff, strlen(buff));
  close(pipefd[1]);

  if (write(pipefd[1], argv[1], size) != size) {
     perror("Error writing to pipe\n");
  }
  close(pipefd[1]);

  while ((size = read(pipefd[0], buff, sizeof(buff))) > 0) 
  {
     write(1, buff, size);
  }
  close(pipefd[0]);

你有没有闭合的孩子管道的写端和您的父母是在阻止read

II)您使用的类似while(fgets(...))在一个循环从文件中读取数据。 当有文件中的新行,这将炸弹fgets返回多次,覆盖buffer的过程中,每次

我总是用简单的fgetcfeof组合从文件中读取。 因此,改变你的文件读取机制,像

unsigned count=0;
while (!feof(file) && count < sizeof(buff))
    buff[count++]=fgetc(file);
if (feof(file)) 
    buff[--count]=0;
else
    buff[sizeof(buff)-1]=0;

III)在写从子文件数据, 你应该使用strlen (因为我们已经取得了一定缓冲空终止,见上文),而不是sizeof作为缓冲可能不是完全的一切 ,你会写出来的垃圾。 所以,变化

  write(pipefd[1], buff, sizeof(buff));

  write(pipefd[1], buff, strlen(buff));

IV)按照安全exit从孩子和家长他们的工作完成之后。 就像是

close(pipefd[1]);
_exit(EXIT_SUCCESS);   // in child

close(pipefd[0]);
exit(EXIT_SUCCESS); // in parent

PS:我已经修改了文件读取逻辑,那么现在你的编译器错误消失,并做好后续通过纳米给出的建议。



Answer 2:

你可以不写sizeof(buf)有意义的字节,如果fgets返回小于。 其余部分将被填满的垃圾。

此外,混合面向字符串的fgets二进制read/write是一个糟糕的风格。 使用readfread读取文件。 他们返回读取的字节数,使用该号码作为一个参数write



Answer 3:

此代码不能编译:

  while (fgets(buff, sizeof(buff), file) != NULL) {
        write(pipefd[1], "Error reading file", 18);
     } else {
        write(pipefd[1], buff, sizeof(buff));
     }

你不能有else条款存在。



文章来源: Program that read file and send it to parent process with pipe
标签: c linux pipe