我尝试使用fgets从C程序(gcc -std = c99)中的命名管道中提取数据。我在命令行创建了管道,我可以看到它存在于文件系统中,并在使用" ls -la"时停放了p。并且任何人都可以使用权利。
prw-rw-rw- 1 www-data www-data 0 Dec 23 00:39 mypipe
我使用简单的脚本将数据发送到管道:
#script
myPipe="/tmp/mypipe"
for j in {0..255}
do
# echo "C $j" #when this is enabled slightly more data gets through
echo "C $j" >> $myPipe
# sleep 0.00000000000001 #when this is enabled all the data gets through
done
我的程序试图从这个管道读取的循环是:
void * reader(){
int messages = 0; // keep track of how many messages we process
char buf[PIPE_BUF]; buf[0] = 0; //#defined PIPE_BUF 1024
int x=100, y=101, z=102, count=103; //initialized to unlikely initial input results
char linetag[PIPE_BUF]; linetag[0] = 0; //space to store the data label
char * pScan = NULL;
FILE *myStream ;
syslog (LOG_INFO, "Reader started\n");
myStream = fopen(pipeName, "r");
if ( myStream == NULL ) {
syslog (LOG_INFO, "Could not open pipe %s as input to Cota\n", pipeName ) ;
return 0;
}
while (1) {
//>>> This was the problem and removing it seems to fix the issue
//freopen(pipeName, "r", myStream); <<<<This was the problem !!!!
pScan==buf;
syslog (LOG_INFO, "readp-1:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
while ( (pScan = fgets(buf, PIPE_BUF, myStream)) == NULL){};
if (pScan == NULL){syslog (LOG_WARNING, "ERROR NULL pScan error");}
syslog (LOG_INFO, "readp-2:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
count = sscanf(pScan, "%s %d %d %d", linetag, &x, &y, &z);
syslog (LOG_INFO, "readp-3:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
messages++;
}
}
当我按上面所述运行脚本时,我的syslog显示以下内容:
Reader started
readp-1:msg:0 >><<>>(null)<< pBuf=0xbe885df4, pScan=(nil), count=103, tag=, x=100, y=101, z=102
readp-2:msg:0 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=103, tag=, x=100, y=101, z=102
readp-3:msg:0 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-1:msg:1 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-2:msg:1 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-3:msg:1 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-1:msg:2 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-2:msg:2 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-3:msg:2 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-1:msg:3 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-2:msg:3 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-3:msg:3 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-1:msg:4 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-2:msg:4 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-3:msg:4 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-1:msg:5 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-2:msg:5 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-3:msg:5 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-1:msg:6 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-2:msg:6 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-3:msg:6 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-1:msg:7 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-2:msg:7 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-3:msg:7 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-1:msg:8 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-2:msg:8 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-3:msg:8 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-1:msg:9 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-2:msg:9 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-3:msg:9 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-1:msg:10 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-2:msg:10 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-3:msg:10 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-1:msg:11 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-2:msg:11 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-3:msg:11 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-1:msg:12 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-2:msg:12 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-3:msg:12 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-1:msg:13 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-2:msg:13 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-3:msg:13 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-1:msg:14 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-2:msg:14 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-3:msg:14 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-1:msg:15 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-2:msg:15 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-3:msg:15 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-1:msg:16 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-2:msg:16 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-3:msg:16 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-1:msg:17 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-2:msg:17 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-3:msg:17 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-1:msg:18 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-2:msg:18 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-3:msg:18 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-1:msg:19 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-2:msg:19 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-3:msg:19 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-1:msg:20 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-2:msg:20 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-3:msg:20 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=246, y=101, z=102
readp-1:msg:21 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=246, y=101, z=102
数据分析似乎与“C&C”正确对齐。在线的开头。如果在我的脚本中,我将本地终端echo
启用到屏幕,那么我会删除更少的行。如果我启用sleep 0.00000000000001
我能够读取所有数据。我真的需要这个以全速运行并且讨厌通过睡眠减慢速度。我只是过度运行缓冲区,如果可以,可以增加缓冲区大小?我真的很难过。顺便说一句,我使用fgets而不是fscanf,因为我最终需要添加fastcgi和fsastcgi似乎缺乏对fscanf的支持(注意在这个测试中我使用的是标准的io库,我没有在fastcgi链接而且我是不包括&#34; fcgi / include / fcgi_stdio.h&#34;在此测试中没有覆盖默认的库)。任何使这一点变得可靠和有效的方向将不胜感激。
答案 0 :(得分:2)
FIFO是有趣的(特殊的)文件。阅读过程一直打开,直到有一个作家;写作过程会一直打开,直到有读者为止。如果没有作家,读者将获得EOF;此时,它必须关闭FIFO并重新打开它以允许更多的编写者。如果没有读取器或写入器,则丢弃FIFO的内容。在shell脚本中,您反复打开和关闭FIFO。你最好把>> $myPipe
移到循环的done
行,这样就会打开一次FIFO,然后写入所有的消息,然后关闭FIFO。
你的代码很特别。这条线存在问题:
while ((pScan = fgets(buf, PIPE_BUF, myStream)) == NULL){};
我看到两个问题。不太严重的是你在空循环体之后有一个空语句。除了向经验丰富的读者展示您对C代码没有信心之外,这不会有任何损害。 {}
就足够了;它是一个空的循环体。下一行的分号代替{}
将是常规的。
更严重的问题是,如果你进入循环,你将无限期地留在它里面。一旦myStream
报告EOF(通过从NULL
返回fgets()
,它将无限期地继续这样做(除非你在Linux上并且输入设备实际上是一个终端 - 这是一个单独的跟我一起疼痛。)
似乎问题中的代码在被询问后被黑客攻击,并且循环顶部的freopen()
行被注释掉了,这就“解决了”问题。这是可以解释的。当FIFO关闭以重新打开时,内容被丢弃。
更好的代码可能看起来更像这样。它将管道名称直接传递给函数(尽可能避免使用全局变量)。该函数仅在无法打开FIFO时才返回。返回NULL的函数没有明显的需要或好处(写0
- 它没关系;我也这样做了),所以它现在是void
函数。函数声明应该在头文件中,而不是在代码中内联写入。
总的来说,我将大多数变量移到他们第一次使用的位置 - 只有messages
才能保持在无限循环之外。将有一个标题来声明各种函数
#include <syslog.h>
#include <stdio.h>
#define PIPE_BUF 1024
extern void reader(const char *pipeName);
void reader(const char *pipeName)
{
int messages = 0;
char buf[PIPE_BUF];
int x = 100, y = 101, z = 102, count = 103;
char linetag[PIPE_BUF];
syslog(LOG_INFO, "Reader started\n");
while (1)
{
FILE *myStream = fopen(pipeName, "r");
if (myStream == NULL)
{
syslog(LOG_INFO, "Could not open pipe %s as input to Cota\n", pipeName);
return;
}
while (fgets(buf, sizeof(buf), myStream) != 0)
{
count = sscanf(buf, "%s %d %d %d", linetag, &x, &y, &z);
syslog(LOG_INFO, "readp-3:msg:%i >>%s<< count=%i, tag=%s, x=%d, y=%d, z=%d\n",
messages, buf, count, linetag, x, y, z);
messages++;
}
fclose(myStream);
}
/* NOTREACHED */
syslog(LOG_INFO, "Reader finished\n");
}