Cygwin FIFO 与本机 Linux FIFO - 阻塞行为存在差异?

Cygwin FIFO vs native Linux FIFO - discrepancy in blocking behaviour?

显示的代码基于使用某个教程站点中的命名管道的示例

server.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define FIFO_FILE "MYFIFO"

int main()
{
        int fd;
        char readbuf[80];
        int read_bytes;

        // mknod(FIFO_FILE, S_IFIFO|0640, 0);
        mkfifo(FIFO_FILE, 0777);
        while(1) {
                fd = open(FIFO_FILE, O_RDONLY);
                read_bytes = read(fd, readbuf, sizeof(readbuf));
                readbuf[read_bytes] = '[=11=]';
                printf("Received string: \"%s\". Length is %d\n", readbuf, (int)strlen(readbuf));
        }
        return 0;
}

在 Windows 中使用 Cygwin 执行服务器时,服务器进入意外循环,重复相同的消息。例如,如果你写成 shell:

$ ./server
|

然后 "server" 等待客户端,但是当 FIFO 不为空时,例如写一个新的 shell

$ echo "Hello" > MYFIFO

然后服务器进入无限循环,重复"Hello"-string

Received string: "Hello". Length is 4
Received string: "Hello". Length is 4
...

此外,服务器似乎不会读取写入 fifo 的新字符串。然而,在 Linux 中,行为是完全不同的。在 Linux 中,服务器打印字符串并等待新数据出现在 fifo 上。造成这种差异的原因是什么?

您需要修复代码以移除至少 3 个错误:

你没有做 close(fd) 所以你会得到一个文件描述符泄漏并最终无法 open() 新文件。

您没有检查 fd 的值(如果 returns -1 则出现错误)。

你没有检查 read 的值(如果它 returns -1 那么有一个错误)......你的 readbuf[read_bytes] = '[=16=]'; 不会做你期望的结果。

当您遇到错误时,errno 会告诉您哪里出了问题。

这些错误可能解释了为什么您总是得到 Hello 输出(尤其是 readbuf[read_bytes] 问题)。