mkfifo使2个进程相互通信

时间:2017-08-30 14:18:15

标签: c ipc mkfifo

我正在尝试编写2个程序,这些程序将使用fifo管道相互通信。 我使用了示例here(第5.2节),但我将mknod更改为mkfifo并尝试将gets更改为fgets。 这是代码(一个写入fifo的程序):

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h> /*mkfifo, open */
#include <sys/wait.h>
#include <sys/stat.h> /* mkfifo, open */
#include <fcntl.h> /*open */

#define FIFO_PATH "/home/hana/Desktop"
#define BUFFER_SIZE 300



int main()
{
    char buffer[BUFFER_SIZE];
    int fd;
    int wStatus;

    mkfifo(FIFO_PATH, 666);
    printf("waiting for readers\n");
    fd = open(FIFO_PATH, O_RDWR);

    while (fgets(buffer, BUFFER_SIZE, fd), !feof(stdin)) 
    {
        if ((wStatus = write(fd, buffer, strlen(buffer))) == -1)
            perror("write");
        else
            printf("speak: wrote %d bytes\n", wStatus);
    }

    return 0;
}

我收到编译错误:传递fgets参数3使得指针来自整数。 所以fgets期待FILE *而不是文件描述符。 我该怎么办?改变一些东西,以便fgets工作?使用其他功能?

我正在用gcc(ansi,pedantic)编译。

由于

2 个答案:

答案 0 :(得分:1)

whjm的答案是你的错误诊断的原因,但我想你可能意味着

fgets(buffer, BUFFER_SIZE, stdin)
//                         ^^^^^ 

从管道读取然后立即将相同的东西写回管道是没有意义的。此外,如果您从未阅读过stdinfeof(stdin)永远不会成真。

另外,使用fgets只检查null结果然后在循环外部,检查eof:

while (fgets(...) != NULL)
{
    ...
}
if (!feof(stdin))
{
    // error handling
}

答案 1 :(得分:0)

mkfifo()只是在文件系统中创建特殊节点。你可以自由地以任何方式打开它。实际上有两种选择 - POSIX&#34;非缓冲&#34; I / O:open()/write()/read()或标准缓冲I / O:fopen()/fread()/fwrite()。第一个家族使用文件描述符,而第二个家族使用所谓的文件流:FILE。您无法自由混合这些API。只需选择一个并坚持下去。 与低级非缓冲I / O相比,标准I / O库提供了一些有用的额外功能。与您尝试使用的fgets()一样。在这种情况下,使用标准流并将open()替换为:

是合理的
FILE* stream = fopen(FIFO_PATH, "r+");

因此程序将使用FILE*而不是普通文件描述符。同时write()需要更改为fwrite(),然后紧跟fflush()以保证写入的数据传递到FIFO。

P.S。如果有必要,可以包装&#34;包装&#34; open()(或其他)使用标准FILE*返回的低级描述符。见fdopen()。但这非常类似于使用标准I / O API以及无法使用fopen()打开的特殊文件对象的解决方法。