使用管道在进程

时间:2016-06-21 21:25:21

标签: c pipe

我正在尝试将我的代码从C#重写为C并遇到一些麻烦。

所以我有一个名为test的文件,其中只有一行文本。我想读取该行,在进程之间通过管道发送它并在屏幕上打印。

以下是代码:

    #include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


void
read_from_pipe (int file)
{
  FILE *stream;
  int c;
  stream = fdopen (file, "r");
  while ((c = fgetc (stream)) != EOF)
    putchar (c);
  fclose (stream);
}

void
write_to_pipe (int file)
{
  FILE *stream;
  FILE *testfile;
  stream = fdopen (file, "w");
  testfile = fopen("test.txt", "r");
  char *line = NULL;
  size_t len = 0;
  //ssize_t read;
  getline(&line, &len, testfile);
  fprintf (stream, "%s", line);
  free(line);
  fclose(testfile);
  fclose (stream);
}

int
main (void)
{
  pid_t pid;
  int mypipe[2];


  if (pipe (mypipe))
    {
      fprintf (stderr, "Pipe failed.\n");
      return EXIT_FAILURE;
    }
  pid = fork ();
  if (pid == (pid_t) 0)
    {
      close (mypipe[1]);
      read_from_pipe (mypipe[0]);
      return EXIT_SUCCESS;
    }
  else if (pid < (pid_t) 0)
    {
      fprintf (stderr, "Fork failed.\n");
      return EXIT_FAILURE;
    }
  else
    {
      close (mypipe[0]);
      write_to_pipe (mypipe[1]);
      return EXIT_SUCCESS;
    }
}

但是,在运行此代码时,我似乎遇到了分段错误。有什么我想念的吗?

3 个答案:

答案 0 :(得分:1)

创建print (df + df.T - df[df==df.T].fillna(0)) a b c a 1.0 1.0 1.0 b 1.0 1.0 -1.0 c 1.0 -1.0 1.0 文件后,它可能会正常工作。 至少在我的机器上修好了它。

在C语言中,你通常需要做一些非常繁琐的错误检查来强有力地编写程序。例如,你应该写一些类似的东西:

test.txt

如果测试文件的int read_from_pipe (int file) { FILE *stream; int c; if((stream = fdopen (file, "r"))==NULL) goto err; while ((c = fgetc (stream)) != EOF){ putchar (c); } if(ferror(stream)){ int er=errno; fclose (stream); errno=er; goto err; } return 0; err: perror("read"); return -errno; } 行看起来像:

fopen

你可能收到了很好的if(!(testfile = fopen("test.txt", "r"))) { perror("write"); return -errno; } 消息。

答案 1 :(得分:1)

您的程序崩溃有几种可能性,但很可能是因为您缺少一些重要的检查,并且程序的工作目录中缺少“test.txt”文件。

首先检查缺少的是testfile是否为NULL:

testfile = fopen("test.txt", "r");

将测试文件FILE指针未经检查传递给getline(),如果程序传递了无效的文件指针,可能会使程序崩溃。 正如Barmar先前所说,即使testfile有效,getline()本身也可能会失败,但是在我当前的Debian上,联机帮助页没有说明错误条件下行指针会发生什么,所以我只检查返回值&lt; 0检测错误,在你的情况下,之后根本不使用或释放​​指针。

作为最后一句话,如果你正在学习这种东西,你应该学习如何使用gdb。 像这样使用:

$ gcc -ggdb3 -o pipetest pipetest.c
$ gdb pipetest 
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
[...]
(gdb) run
Starting program: /home/thilo/code/test/pipetest 

Program received signal SIGSEGV, Segmentation fault.
_IO_getdelim (lineptr=0x7fffffffe068, n=0x7fffffffe060, delimiter=10, fp=0x0) at iogetdelim.c:56
56      iogetdelim.c: No such file or directory.
(gdb) bt
#0  _IO_getdelim (lineptr=0x7fffffffe068, n=0x7fffffffe060, delimiter=10, fp=0x0) at iogetdelim.c:56
#1  0x00000000004008fb in write_to_pipe (file=4) at pipetest.c:28
#2  0x00000000004009d9 in main () at pipetest.c:62
(gdb) frame 1
#1  0x00000000004008fb in write_to_pipe (file=4) at pipetest.c:28
28        getline(&line, &len, testfile);
(gdb) print line
$1 = 0x0

答案 2 :(得分:0)

此代码在我的机器上正常运行(Linux 3.2.0-4-amd64#1 SMP Debian 3.2.68-1 + deb7u2 x86_64 GNU / Linux),无需修改。 我删除了'test.txt'文件,结果出现了分段错误。

因此,我认为您遇到的问题是“test.txt”文件不存在,或者您没有对运行该程序的用户具有读取权限。