键盘输入被错误地重定向到命名管道读取
Keyboard Input is wrongly redirected to Named Pipe read
我发布了一个 earlier question 我还没有解决。我稍后会在那里尝试答案。但是,我目前面临一个奇怪的问题。
我运行在两个不同的ssh
-ed终端上连接我的reader
和writer
。
我在命名管道中的 reader 正在从键盘而不是命名管道读取输入。这是我的简单 reader.
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
reader 端行为异常。它正确地等待管道先被打开。然后,它不显示任何输出。如果我按 "enter" 它只会显示空白。如果按"ab",则分别输出"a"和"b"。这是一个示例输出:
Waiting on open
waiting on read
Read:
Read:
Read:
a
Read: a Read:
ab
Read: a Read: b Read:
我先 运行 reader 然后等待 open
。当 writer 启动时,它等待 read
但不显示任何输出。只有当我按任何输入时,它才会显示一些东西。任何人都可以提供任何 hint/idea 到底发生了什么吗?
这里有一个运算符优先级问题。赋值运算符 (=
) 的优先级低于 <
等比较运算符。因此,这个 while
循环 ...
while(Pipe_FD = open(PIPE_ID, O_RDONLY) < 0) {
}
被解释为
while (Pipe_FD = (open(PIPE_ID, O_RDONLY) < 0)) {
}
当open()
returns 小于0时,它具有您想要的语义,因为关系表达式的计算结果为1,1被分配给Pipe_FD
,整体的价值表达式为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);
}
}
我建议也在那里放一个短暂的延迟,这样对系统资源的要求会低一些。
我发布了一个 earlier question 我还没有解决。我稍后会在那里尝试答案。但是,我目前面临一个奇怪的问题。
我运行在两个不同的ssh
-ed终端上连接我的reader
和writer
。
我在命名管道中的 reader 正在从键盘而不是命名管道读取输入。这是我的简单 reader.
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
reader 端行为异常。它正确地等待管道先被打开。然后,它不显示任何输出。如果我按 "enter" 它只会显示空白。如果按"ab",则分别输出"a"和"b"。这是一个示例输出:
Waiting on open
waiting on read
Read:
Read:
Read:
a
Read: a Read:
ab
Read: a Read: b Read:
我先 运行 reader 然后等待 open
。当 writer 启动时,它等待 read
但不显示任何输出。只有当我按任何输入时,它才会显示一些东西。任何人都可以提供任何 hint/idea 到底发生了什么吗?
这里有一个运算符优先级问题。赋值运算符 (=
) 的优先级低于 <
等比较运算符。因此,这个 while
循环 ...
while(Pipe_FD = open(PIPE_ID, O_RDONLY) < 0) { }
被解释为
while (Pipe_FD = (open(PIPE_ID, O_RDONLY) < 0)) {
}
当open()
returns 小于0时,它具有您想要的语义,因为关系表达式的计算结果为1,1被分配给Pipe_FD
,整体的价值表达式为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);
}
}
我建议也在那里放一个短暂的延迟,这样对系统资源的要求会低一些。