opening a file

R

rihad

This function is from a daemon (long-lived process):

sub foo($) {
my ($command) = shift;

BEGIN {
open(FOO, ">/var/tmp/foo") or return;
my $old_fh = select(FOO);
$| = 1;
select($old_fh);
}

print FOO "$command\n";

END {
close(FOO);
}
}

/var/tmp/foo is a FIFO (mkfifo). It also has a reader daemon (not
shown).
Now when foo('blah-blah-blah') is called, nothing gets written to the
FIFO. Even if I call it several times in succession. I need to stop
the Perl daemon to see them finally output. If I get rid of the BEGIN/
END surroundings, everything works, but opening and closing the fifo
every time is a performance hit for me. Maybe I'm not using autoflush
and select in BEGIN properly? Please help, as I'm not experienced with
Perl.

Perl v5.8.8
FreeBSD 7.0
 
R

rihad

Did you tried using:
open(FOO, ">> /var/tmp/foo") or return;
Still the same. BTW: why would changing to append mode affect the
result?
open FOO, '>', '/var/tmp/foo' or die "Can't open > /var/tmp/foo
Come on... we aren't language lawyers taking a cup of coffee during
lunch, are we? Your comments make me no closer to the solution.
 
J

John W. Krahn

rihad said:
This function is from a daemon (long-lived process):

sub foo($) {
my ($command) = shift;

BEGIN {
open(FOO, ">/var/tmp/foo") or return;
my $old_fh = select(FOO);
$| = 1;
select($old_fh);
}

print FOO "$command\n";

END {
close(FOO);
}
}

/var/tmp/foo is a FIFO (mkfifo). It also has a reader daemon (not
shown).
Now when foo('blah-blah-blah') is called, nothing gets written to the
FIFO. Even if I call it several times in succession. I need to stop
the Perl daemon to see them finally output.

Nothing gets written? Or it does get written when you close the
filehandle (stop the Perl daemon?)

Unlike a terminal which has line buffering, it looks like you are
encountering full buffering which does not output on every newline.

Perhaps you might try unbuffered IO with sysopen and syswrite instead of
open and print:

perldoc -f sysopen
perldoc -f syswrite
perldoc perlopentut
man 2 open


John
 
A

Andrew DeFaria

rihad said:
Come on... we aren't language lawyers taking a cup of coffee during
lunch, are we?
It's lunch time already? What's for lunch?

No we aren't language lawyers - we're Perl programmers...
Your comments make me no closer to the solution.
Surely you can't be serious? Putting out actually real live error
messages when something bad happens is a time honored tradition in the
programming profession! Seriously now, why would you *not* want to say
what went wrong when something goes wrong! It's often the first step in
figuring out what is going wrong. And it's something you should be doing
regardless. Geeze, do I really need to tell you this?
 
R

rihad

/var/tmp/foo is a FIFO (mkfifo). It also has a reader daemon (not
Nothing gets written? Or it does get written when you close the
filehandle (stop the Perl daemon?)
Yeah, they do get written when it's stopped, just like I think I
said ;)
Unlike a terminal which has line buffering, it looks like you are
encountering full buffering which does not output on every newline.
But but but... shouldn't $| = 1; flush the buffer upon every print?
See perlfaq5.
Perhaps you might try unbuffered IO with sysopen and syswrite instead of
open and print:

perldoc -f sysopen
perldoc -f syswrite
perldoc perlopentut
man 2 open
Thanks, I'll give them a try and see how it goes.
Geeze, do I really need to tell you this?
Yeah you're right but the messages are surely in the buffer as they
are written as soon as I stop the Perl daemon. See above.
 
S

skeldoy

Try putting the $|=1; at the start of your program (right under any
use-statements that you may have). I have encountered various problems
when trying to reconfigure the buffering on the fly. Only two cents
here. Good luck!
 
J

John W. Krahn

rihad said:
Yeah, they do get written when it's stopped, just like I think I
said ;)

But but but... shouldn't $| = 1; flush the buffer upon every print?
See perlfaq5.

Thanks, I'll give them a try and see how it goes.

Yeah you're right but the messages are surely in the buffer as they
are written as soon as I stop the Perl daemon. See above.

I didn't write that last sentence. Why are you attributing that to me?


John
 
J

John W. Krahn

Try putting the $|=1; at the start of your program (right under any
use-statements that you may have). I have encountered various problems
when trying to reconfigure the buffering on the fly. Only two cents
here. Good luck!

$| only applies to the currently selected filehandle so at the start of
the program that is probably STDOUT.


John
 
X

xhoster

rihad said:
This function is from a daemon (long-lived process):

sub foo($) {
my ($command) = shift;

BEGIN {
open(FOO, ">/var/tmp/foo") or return;

Since the BEGIN isn't actually happening during the sub call,
it is not clear to me what the "or return" is going to do in
case of a failure.
my $old_fh = select(FOO);
$| = 1;
select($old_fh);
}

print FOO "$command\n";

END {
close(FOO);
}
}

/var/tmp/foo is a FIFO (mkfifo). It also has a reader daemon (not
shown).

Are you sure your problem is not in the reader daemon? I can not reproduce
your problem using your code above (and the driver below), and using "cat"
as the reader.

foreach (1..10) {
foo($_);
sleep 5;
};



.....
Perl v5.8.8
FreeBSD 7.0

But I am using Linux rather than FreeBSD. It seems unlikely they would
differ in this regard, but you never know.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
R

rihad

Since the BEGIN isn't actually happening during the sub call,
it is not clear to me what the "or return" is going to do in
case of a failure.
Yeah, I know, but since I'm playing both with and without BEGIN/END I
left return there, as I don't want die to stop the daemon (I know I
can catch die outside, but decided to keep things simple for now. With
BEGIN I'll probably use die when testing is over).
Are you sure your problem is not in the reader daemon? I can not reproduce
your problem using your code above (and the driver below), and using "cat"
as the reader.
Bingo! cat -u works, but tail -f (the real reader frontend) seems to
buffer its input... and there's no option to turn off that buffering
AFAIK. I had never thought I should try another reader. Thanks for the
pointer. I must use tail -f because I don't want the real daemon to
exit on EOF (as there are several writers, not only the one shown
here, but also short-lived processes). But since the Perl daemon never
closes its writing part of the FIFO when BEGIN/END are used, cat
should never exit anyway if I make sure the daemon runs before short-
lived writers. Now with cat in place everything works, so this wasn't
a misunderstanding of Perl on my part, but rather of tail -f Thanks to
everyone too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top