C语言 mkfifo使2个进程彼此对话

xzv2uavs  于 2023-03-07  发布在  其他
关注(0)|答案(2)|浏览(145)

我试着写两个程序,它们将使用fifo管道互相对话。我使用了这里的例子(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是期待文件 * 而不是文件描述符.我应该怎么做?改变一些东西使fgets工作?使用另一个函数?
我正在编译与gcc(ansi,学究气)。
谢谢

9vw9lbht

9vw9lbht1#

whjm的答案是错误诊断的原因,但我想您的意思可能是

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

从管道中读取数据,然后立即将相同的内容写回管道是没有意义的,而且,如果您从未从stdin中读取数据,feof(stdin)就永远不会为真。
同样,使用fgets只检查null结果,然后在循环之外检查eof:

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

sf6xfgos2#

mkfifo()只是在文件系统中创建了一个特殊的节点,你可以自由地以任何方式打开它。实际上有两种选择- POSIX“非缓冲”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.在必要的情况下,可以使用标准的FILE*“ Package ”open()(或其他东西)返回的低级描述符。请参见fdopen()。但是,使用标准的I/O API处理无法使用fopen()打开的特殊文件对象,这很像是一种变通方案。

相关问题