[英]How to read and write to a fifo (named pipe) in Linux?
我正在嘗試打開一個fifo(命名管道)文件,然后將其寫入。 我似乎無法讓服務器看到“客戶端”寫入的內容。
注意:為簡單起見,我使用的術語類似於“客戶端-服務器”。 我意識到他們實際上只是同齡人,而且任何一方都可以關閉管道。
pipetest_server.c
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
int keep_going = 1;
static void signal_handler(int signum)
{
keep_going = 0;
}
int main()
{
int fd;
char *myfifo = "/tmp/mypipe";
char *line;
ssize_t amount_read;
ssize_t len;
FILE *f;
signal(SIGINT, signal_handler);
signal(SIGABRT, signal_handler);
signal(SIGTERM, signal_handler);
// make pipe
mkfifo(myfifo, 0666);
// open it
fd = open(myfifo, O_RDWR);
// make non-blocking
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
// make a file descriptor for pipe
f = fdopen(fd, "rw");
while(keep_going)
{
amount_read = getline(&line, &len, f);
if (amount_read > 0)
printf(line);
}
printf("quitting...\n");
close(fd);
unlink(myfifo);
return 0;
}
然后:
$ gcc pipetest_server.c
$ ./a.out
在另一個終端:
$ ls -la /tmp/mypipe
prw-rw-r--. 1 myuser myuser 0 Nov 20 12:58 /tmp/mypipe
好的-此時,這里有一個管道。 現在解決問題
1)用回波寫入管道。 什么都沒發生
$ echo Hi >> /tmp/mypipe
<nothing comes out of the server>
2)給管子加襯管,顯示數據
$ cat /tmp/mypipe
Hi
<blinking cursor>
發生了什么....
服務器從不獲取數據,但是管道中包含數據。
3)當我關閉服務器時,管道消失了
<ctrl-C>
^Cquitting...
這告訴我服務器確實創建了管道並對其進行了控制。
4)我真的很想創建另一個程序來寫入管道
最終,我希望有另一個程序將寫入此管道,並且兩個程序將通過該管道進行通信。
注意:還有其他關於此的SO文章,但沒有一篇文章很重要。
更新-工作代碼
這是萬一有人追趕的最終解決方案。
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
static volatile sig_atomic_t keep_going = 1;
static void signal_handler(int signum)
{
keep_going = 0;
}
int main()
{
int fd;
char *myfifo = "/tmp/mypipe";
char *line;
ssize_t amount_read;
ssize_t len;
FILE *f;
signal(SIGINT, signal_handler);
signal(SIGABRT, signal_handler);
signal(SIGTERM, signal_handler);
// make pipe
mkfifo(myfifo, 0666);
// open it
fd = open(myfifo, O_RDWR);
// make non-blocking
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
// make a file descriptor for pipe
f = fdopen(fd, "rw");
while(keep_going)
{
amount_read = getline(&line, &len, f);
if (amount_read > 0)
printf(line);
if (amount_read == -1)
{
clearerr(f);
}
}
printf("quitting...\n");
close(fd);
unlink(myfifo);
return 0;
}
問題是您已將文件描述符設置為非阻塞,然后使用fdopen在其上打開了一個FILE *
。 Stdio FILE流不理解非阻塞I / O,因此在您第一次調用getline
時,讀取將失敗(使用EWOULDBLOCK或EGAIN),並且FILE將進入錯誤狀態,並且getline將返回-1。 一旦FILE處於錯誤狀態,每個調用將立即返回-1,而無需實際嘗試再次讀取。
如果要實際使用非阻塞模式,則需要在getline返回-1之后調用clearerr(f)
。 您還應該檢查errno,以確保錯誤是EWOULDBLOCK或EAGAIN -如果存在真正的錯誤,則可能是其他錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.