简体   繁体   English

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

[英]Keyboard Input is wrongly redirected to Named Pipe read

I posted an earlier question which I am yet to solve. 我发布了一个尚待解决的较早的问题 I'll try out the answer there later. 我稍后会在那里尝试答案。 However, I am currently facing a strange problem. 但是,我目前面临一个奇怪的问题。

I am running my reader and writer on two different ssh -ed terminals . 我正在我的readerwriter两个不同ssh -ed终端 My reader in a named pipe is reading input from the keyboard instead of the named pipe. 我在命名管道中的读取器正在从键盘而不是命名管道读取输入。 Here is my simple reader. 这是我的简单读者。

reader.c 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;
}

My writer configures the pipe, writes a "Hi" to the named pipe and then sleeps for 1 second before exiting. 我的作者配置了管道,在命名管道中写入“ Hi”,然后在退出之前休眠1秒钟。

writer.c 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);
}

The writer end correctly outputs: 编写器端正确输出:

Wrote bytes: 3

The reader end behaves strangely. 读者端表现异常。 It correctly waits for the pipe to be opened first. 它正确地等待管道首先被打开。 Then, it doesn't show any output. 然后,它不显示任何输出。 If I press "enter" it just reads blank. 如果我按“输入”,它将显示为空白。 If press "ab", it outputs "a" and "b" separately. 如果按“ ab”,它将分别输出“ a”和“ b”。 Here's an sample output: 这是一个示例输出:

Waiting on open
waiting on read

Read:

        Read:

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

I run the reader first and then it waits on open . 我先运行阅读器,然后等待open When the writer starts, it waits on read but doesn't show any output. 编写器启动时,它会等待read但不显示任何输出。 Only when I press any enter, then it shows something. 只有当我按下任何回车键时,它才会显示某些内容。 Can anybody give any hint/idea what is happening really? 任何人都可以给出任何提示/想法到底是什么情况吗?

You have an operator precedence problem here. 您这里有一个运算符优先级问题。 The assignment operator ( = ) has lower precedence than the comparison operators such as < . 赋值运算符( = )的优先级低于比较运算符(如< Therefore, this while loop ... 因此,此while循环...

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

is interpreted as 被解释为

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

That has the semantics you intend when open() returns less than 0, for then the relational expression evaluates to 1, 1 is assigned to Pipe_FD , the value of the overall expression is 1, and the loop continues iterating. open()返回小于0时,这具有您想要的语义,然后关系表达式的计算结果为1,将1分配给Pipe_FD ,整个表达式的值为1,然后循环继续迭代。

When the open() succeeds , however, the actual file descriptor is used only for the comparison with 0. When the FD is non-negative, the comparison evaluates to 0, 0 is assigned to Pipe_FD , the value of the overall expression is 0, and the loop terminates. open() 成功时,实际文件描述符仅用于与0的比较。当FD为非负数时,比较结果为0,0 分配给Pipe_FD ,整个表达式的值为0 ,循环终止。 That leaves you afterward reading from file descriptor 0, the standard input, instead of from the FIFO you opened. 这样一来,您就可以从标准输入文件描述符0中读取内容,而不是从您打开的FIFO中读取内容。

Fix the problem by appropriate use of parentheses: 通过适当使用括号来解决问题:

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

Additionally, it would be both more robust and clearer to test in the loop body why opening failed. 此外,在循环主体中测试为什么打开失败会更加健壮和清晰。 For example, 例如,

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

I would suggest also putting a short delay in there, so as to be a little less demanding of system resources. 我建议在该位置稍加延迟,以减少对系统资源的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM