c - 键盘输入错误地重定向到命名管道读取
问题描述
我发布了一个尚未解决的较早问题。我稍后会在那里尝试答案。但是,我目前面临一个奇怪的问题。
我在两个不同的终端reader
上运行我的和。我在命名管道中的阅读器正在从键盘而不是命名管道读取输入。这是我的简单读者。writer
ssh
读者.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 秒。
作家.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
但不显示任何输出。只有当我按下任何输入时,它才会显示一些东西。任何人都可以给出任何提示/想法到底发生了什么?
解决方案
您在这里遇到了运算符优先级问题。赋值运算符 ( =
) 的优先级低于比较运算符,例如<
. 因此,这个while
循环...
while(Pipe_FD = open(PIPE_ID, O_RDONLY) < 0) { }
被解释为
while (Pipe_FD = (open(PIPE_ID, O_RDONLY) < 0)) {
}
open()
当返回小于 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);
}
}
我建议还在那里放一个短暂的延迟,以便对系统资源的要求不那么高。
推荐阅读
- jooq - 使用 Jooq 作为 SQL Builder
- genexus - GeneXus 16 .NET U10 - 导入 OpenAPI - 支持 OpenAPI 3.0.0?
- nuxt.js - 如何检查应用程序的 Nuxt.js 版本?
- windows - 在 Windows 中禁用文件协议
- javascript - 未收到来自 PHP 的 json 响应,并且 PHP 错误日志或控制台中没有错误
- c# - SSIS脚本任务获取csv文件的行数
- reactjs - 为什么在 React 应用程序中使用 @import 来使用谷歌字体?
- c# - 正则表达式自定义开始和结束引号.Net
- scala - 编译|构建错误 Maven [错误]:xsbti.CompileFaile
- spring - 如何从外部 Jar 中自动装配实体?