Cygwin FIFO против родного Linux FIFO - несоответствие в поведении блокировки? - PullRequest
0 голосов
/ 02 января 2019

Показанный код основан на примере использования именованных каналов с какого-либо учебного сайта

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] = '\0';
                printf("Received string: \"%s\". Length is %d\n", readbuf, (int)strlen(readbuf));
        }
        return 0;
}

При запуске сервера в Windows с использованием Cygwin сервер входит в нежелательный цикл, повторяя то же сообщение. Например, если вы пишете в оболочке:

$ ./server
|

тогда «сервер» ждет клиента, но когда FIFO не пуст, например, писать в новой оболочке

$ echo "Hello" > MYFIFO

затем сервер входит в бесконечный цикл, повторяя строку «Hello»

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

Кроме того, новые строки, записанные в fifo, по-видимому, не читаются сервером. Однако в Linux поведение совсем другое. В Linux сервер печатает строку и ожидает появления новых данных на fifo. В чем причина этого несоответствия?

1 Ответ

0 голосов
/ 02 января 2019

Вам нужно исправить свой код, чтобы удалить как минимум 3 ошибки:

Вы не делаете close(fd), поэтому вы получите утечку файлового дескриптора и в конечном итоге не сможете open() новых файлов.

Вы не проверяете значение fd (если оно возвращает -1, то произошла ошибка).

Вы не проверяете значение read (если оно возвращает -1, значит, произошла ошибка) ... и ваш readbuf[read_bytes] = '\0'; не будет делать то, что вы ожидаете в результате.

Когда вы получите сообщение об ошибке, errno сообщит вам, что пошло не так.

Эти ошибки, вероятно, объясняют, почему вы получаете вывод Hello (особенно проблема readbuf[read_bytes]).

...