2017-08-30 68 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