键盘输入错误地重定向到读取的命名管道

时间:2018-06-21 17:52:50

标签: c linux ipc named-pipes

我发布了一个earlier question,但我还没有解决。我稍后会在那里尝试答案。但是,我目前面临一个奇怪的问题。

我正在{strong>两个不同的reader版本的终端机上运行writerssh 。 我在命名管道中的读取器正在从键盘而不是命名管道读取输入。这是我简单的读者。

reader.c

#define PIPE_ID "aa"
int Pipe_FD = 0;

int main (int argc, char **argv)
{    
  printf("Waiting on open\n");
  while(Pipe_FD = open(PIPE_ID, O_RDONLY) < 0) {
  }

  printf("waiting on read\n");
  char ch;
  while(read(Pipe_FD, &ch, 1) > 0) {
    printf("Read: %c\t", ch);
    fflush(stdout);
  }
  close(Pipe_FD);
  return 1;
}

我的作者配置了管道,在命名管道中写入“ Hi”,然后在退出之前休眠1秒钟。

writer.c

#define PIPE_ID "aa"
int Pipe_FD = 0;

// This function configures named pipe
void configure_pipe() {
  if(mkfifo(PIPE_ID, 0666) != 0) {
    perror("mkfifo error\n");
  }
}

void writeInPipe() {
  Pipe_FD = open(PIPE_ID, O_WRONLY);
  int num;
  if((num = write(Pipe_FD, "Hi", sizeof("Hi"))) < 0) {
    perror("Error in writing\t");
    exit(-1);
  }  else
    printf("Wrote bytes: %d\n", num);
  close(Pipe_FD);
}

int main() {
  configure_pipe();

  writeInPipe();
  sleep(1);
  unlink(PIPE_ID);
}

作者端正确输出:

Wrote bytes: 3

读者端表现异常。它正确地等待管道首先被打开。然后,它不显示任何输出。如果我按“输入”,它将显示为空白。如果按“ ab”,它将分别输出“ a”和“ b”。这是一个示例输出:

Waiting on open
waiting on read

Read:

        Read:

        Read:
a
        Read: a Read:
ab
        Read: a Read: b Read:

我先运行阅读器,然后等待open。编写器启动时,它在read上等待,但不显示任何输出。只有当我按下任何回车键时,它才会显示某些内容。任何人都可以给出任何暗示/想法到底是怎么回事吗?

1 个答案:

答案 0 :(得分:1)

您在这里有一个运算符优先级问题。赋值运算符(=)的优先级比比较运算符<低。因此,此while循环...

while(Pipe_FD = open(PIPE_ID, O_RDONLY) < 0) {
}

被解释为

while (Pipe_FD = (open(PIPE_ID, O_RDONLY) < 0)) {
}

具有open()返回小于0时要使用的语义,因为关系表达式的值为1,Pipe_FD被分配了1,整个表达式的值为1,而循环继续迭代。

但是,open() 成功时,实际文件描述符仅用于与0的比较。当FD为非负时,比较的结果为0, 0被分配给Pipe_FD ,整个表达式的值为0,并且循环终止。这样一来,您便可以从标准输入文件描述符0中读取内容,而不是从打开的FIFO中读取内容。

通过适当使用括号来解决问题:

while ((Pipe_FD = open(PIPE_ID, O_RDONLY)) < 0) {
}

此外,在循环主体中测试为什么为什么失败会更加健壮和清晰。例如,

while ((Pipe_FD = open(PIPE_ID, O_RDONLY)) < 0) {
    if (errno != ENOENT) {
        perror("open");
        exit(1);
    }
}

我建议您也在其中稍加延迟,以减少对系统资源的需求。