View Full Version : preventing FIFO from EOF
rihad
December 12th, 2008, 14:22
$ mkfifo /var/tmp/foo
$ buffer -i /var/tmp/foo # misc/buffer
# in another console:
$ echo hi > /var/tmp/foo
buffer prints hi and exits. I want it to keep reading and printing indefinitely.
Further experimentation revealed that I need two writers: one dummy writer that just keeps /var/tmp/foo open for writing, and the other doing the "real work". This way buffer wouldn't exit. But how to emulate the dummy writer? It itself needs to block on something to keep /var/tmp/foo open. Any clean way to do this in shell? Maybe the solution is quite simple but isn't at the tip of my tongue.
Thanks.
graudeejs
December 12th, 2008, 15:51
i have no idea what i will say now (it might even be stupid, don't blaim, but here are my 2 cents)
filter EOFs and cat the rest
rihad
December 12th, 2008, 17:00
Huh? EOF's are logical, you can't touch them :)
Strangely enough, something as stupid as this does the trick:
on tty1:
$ sh < /dev/stdout > /var/tmp/kick 2>/dev/null
on tty2:
$ buffer -i /var/tmp/foo
on tty3:
$ echo hi > /var/tmp/foo
$
now buffer blocks forever irregardless of whether echo exits as soon as it writes "hi" or not.
I'm not sure what reading from stdout does or why and how it works Unix-wise, but it does work.
SirDice
December 12th, 2008, 17:24
Unix treats everything as a file, including FIFOs.
An echo hi > /var/tmp/foo opens /var/tmp/foo, writes 'hi' to it then closes /var/tmp/foo. That last action triggers an EOF.
rihad
December 13th, 2008, 18:49
Strangely enough, something as stupid as this does the trick:
on tty1:
$ sh < /dev/stdout > /var/tmp/kick 2>/dev/null
Nooo :( this seems to work from console but doesn't in /usr/local/etc/rc.d/file.sh.
I need a lovely Unix device (like /dev/zero or /dev/null) designed to always block on input, so I can substitute /dev/stdout above. Possible?
rihad
December 13th, 2008, 19:05
Finally:
tail -f /var/tmp/foo | buffer
Now buffer never exits.
dap
December 14th, 2008, 15:41
IMO it would be wore straightforward to write a program. Here is a small example:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define FIFO_NAME "/var/tmp/foo"
int main (void)
{
umask(0);
if ( mkfifo(FIFO_NAME, 0666) == -1 && errno != EEXIST )
{
perror("mkfifo()");
}
else
{
int fd = open(FIFO_NAME, O_RDONLY);
if (fd == -1)
{
perror("open()");
}
else
{
char buffer[32];
int error = 0;
while (error == 0)
{
int readRet = read(fd, buffer, sizeof buffer);
if (readRet == -1)
{
perror("read()");
error = 1;
}
/* there is no more reader; close the FIFO and reopen it to wait for */
/* a new one */
else if (readRet == 0)
{
close(fd);
fd = open(FIFO_NAME, O_RDONLY);
}
else
{
buffer[sizeof buffer - 1] = '\0';
printf("Received : [%s]\n", buffer);
}
}
close(fd);
}
}
return EXIT_FAILURE;
}
I have removed some of the error control to make it easier to understand.
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.