2017-08-30 132 views
0

我正在尝试编写2个程序,这两个程序将使用fifo管道相互交谈。 我使用的例子here(5.2节),但我改变了mknod那里mkfifo并试图改变获取fgets。 这是代码(其中写入到FIFO一个程序):mkfifo使2个进程互相交谈

#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,迂腐)。

感谢

回答

0

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*“换行”由open()(或其他)返回的低级描述符。见fdopen()。但它很像使用标准I/O API和无法使用fopen()打开的特殊文件对象的解决方法。

1

从whjm答案是你错误的原因的诊断,但我认为你可能是指

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

它不会让你会从管道立即读取,然后感觉把同样的东西写回管道。此外,如果您从未读过stdin,则feof(stdin)永远不会成立。

此外,用于fgets只检查空结果,然后循环外,做EOF检查:

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

由于OP只询问编译错误以及如何获取'FILE *',所以我没有真正阅读代码。 :) – pynexj

+0

@whjm我不是暗示你的回答是错误的。事实上你的投票是我的。 – JeremyP

+0

我还更改了主题并删除了标签'ipc'和'mkinfo'。刚刚回滚。 :) – pynexj