Skip Menu |

This queue is for tickets about the IO-stringy CPAN distribution.

Report information
The Basics
Id: 11249
Status: resolved
Priority: 0/
Queue: IO-stringy

People
Owner: Nobody in particular
Requestors: kylev-perl [...] kylev.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.109
Fixed in: (no value)



Subject: IO::Scalar flush shouldn't return undef
In CVS rev 2.105 of IO::Scalar there is no-op stub for flush(). This will return undef, which is wrong. Since it is a no-op, it essentially always succeeds. From the IO::Handle docs: "flush" causes perl to flush any buffered data at the perlio api level. Any unread data in the buffer will be discarded, and any unwritten data will be written to the underlying file descriptor. Returns "0 but true" on success, "undef" on error. So, the stub flush() (which returns undef) is exactly wrong. This is now causing problems for us when used in conjuntion with MIME::Parser which dies if flush fails.
From: julian [...] mehnle.net
The attached patch fixes all flush() methods to return "0 but true".
diff -ruN IO-stringy-2.109/lib/IO/InnerFile.pm IO-stringy-2.109-flush-methods-return-wrong-results/lib/IO/InnerFile.pm --- IO-stringy-2.109/lib/IO/InnerFile.pm 2001-08-17 04:06:33.000000000 +0200 +++ IO-stringy-2.109-flush-methods-return-wrong-results/lib/IO/InnerFile.pm 2005-02-09 00:15:32.000000000 +0100 @@ -145,7 +145,7 @@ sub write { shift->WRITE(@_) } sub print { shift->PRINT(@_) } sub printf { shift->PRINTF(@_) } -sub flush { 1; } +sub flush { "0 but true" } sub binmode { 1; } sub getc { return GETC(tied(${$_[0]}) ); } sub read { return READ( tied(${$_[0]}), @_[1,2,3] ); } diff -ruN IO-stringy-2.109/lib/IO/ScalarArray.pm IO-stringy-2.109-flush-methods-return-wrong-results/lib/IO/ScalarArray.pm --- IO-stringy-2.109/lib/IO/ScalarArray.pm 2001-08-09 10:04:44.000000000 +0200 +++ IO-stringy-2.109-flush-methods-return-wrong-results/lib/IO/ScalarArray.pm 2005-02-09 00:14:00.000000000 +0100 @@ -266,7 +266,7 @@ =cut -sub flush {} +sub flush { "0 but true" } #------------------------------ diff -ruN IO-stringy-2.109/lib/IO/Scalar.pm IO-stringy-2.109-flush-methods-return-wrong-results/lib/IO/Scalar.pm --- IO-stringy-2.109/lib/IO/Scalar.pm 2003-12-21 19:51:45.000000000 +0100 +++ IO-stringy-2.109-flush-methods-return-wrong-results/lib/IO/Scalar.pm 2005-02-09 00:12:51.000000000 +0100 @@ -275,7 +275,7 @@ =cut -sub flush {} +sub flush { "0 but true" } #------------------------------
From: kylev-perl [...] kylev.com
Show quoted text
> The attached patch fixes all flush() methods to return "0 but true".
Very funny. I think the author of the IO::Handle docs meant that 0 should be returned, but non-zero is an error. I can't figure out how to interpret it any other way. if ($foo->flush() == 0) { print "Everything flushed fine.\n"; } It really doesn't seem like much from IO::* is doing this correctly. I'm very confused. IO::Handle doesn't even define it, but has it in EXPORT_OK. Is it returning undef too then?
From: kylev-perl [...] kylev.com
Show quoted text
> if ($foo->flush() == 0) { > print "Everything flushed fine.\n"; > }
Note, I think this is the described behaviour since fflush(3) returns 0 on success. Calling it should be familiar to C programmers.
From: julian [...] mehnle.net
[guest - Tue Feb 8 21:05:38 2005]: Show quoted text
> > The attached patch fixes all flush() methods to return "0 but > > true".
> > Very funny. I think the author of the IO::Handle docs meant that 0 > should be returned, but non-zero is an error. I can't figure out how > to interpret it any other way.
It is meant literally. Show quoted text
> if ($foo->flush() == 0) { > print "Everything flushed fine.\n"; > }
Even though it would work (see the very bottom of this message), "$foo->flush() == 0" is not Perl-ish, it is C-ish. In Perl, this should just read... if ($foo->flush()) { print "Everything flushed fine.\n"; } ...i.e. flush() returns a true value if it succeeds. Show quoted text
> Note, I think this is the described behaviour since fflush(3) returns > 0 on success. Calling it should be familiar to C programmers.
Perl's flush() _does_ behave similarly to the system call. It returns numerically 0, but logically true (to make it work Perl-ish). Show quoted text
> It really doesn't seem like much from IO::* is doing this correctly. > I'm very confused. IO::Handle doesn't even define it, but has it in > EXPORT_OK. Is it returning undef too then?
Yes, you are confused. Please read the explanation of T_SYSRET in ext/XS/Typemap/Typemap.xs (in the Perl source): | The T_SYSRET typemap is used to process return values from system | calls. It is only meaningful when passing values from C to perl | (there is no concept of passing a system return value from Perl to | C). | | System calls return -1 on error (setting ERRNO with the reason) and | (usually) 0 on success. If the return value is -1 this typemap | returns C<undef>. If the return value is not -1, this typemap | translates a 0 (perl false) to "0 but true" (which is perl true) or | returns the value itself, to indicate that the command succeeded. Believe me, this is how it is supposed to work. For example: $ perl -e 'print("0 but true" + 0, "\n");' 0 $ perl -e 'print("0 but true" ? "true" : "false", "\n");' true
From: kylev-perl [...] kylev.com
[guest - Sun Feb 13 20:08:38 2005]: Show quoted text
> It is meant literally.
Wow. Ah, the surprising intricacies of perl! I see a new release of IO::Stringy came out on Feb 14 with the "0 but true" patch applied. Thank you! Close the ticket!