Re: [MacPerl-Porters] [ macperl-Bugs-664987 ] IO::File + leading space for hard disk

[email protected] (Bart Lateur) Thu, 09 Jan 2003 22:12:58 +0100
Newsgroups perl.macperl.porters
Organization MediaMind
Message-ID <[email protected]>
On Thu, 9 Jan 2003 17:55:17 +0100, Axel Rose wrote:

>Um 11:13 Uhr -0500 09.01.2003, schrieb Chris Nandor:
>> I -- or someone who wants to -- needs to patch IO::File ...
>
>I'd be willing but fear the consequences for other platforms
>or would it just be a MacPerl only patch?

A consequence would be that it would only work for 5.6.0 and up, because
I think that's when the three argument open() was introduced. That would
imply that future bugfixes on IO::File would be wasted on 5.005_03,
which still is a very popular Perl version -- which replace something
that isn't really broken?

The safer but more complex way, is to always use sysopen(), and thus,
convert the modes into numbers using the constants from Fctnl. I could
have some errors, but I think this about covers it:

	use Fcntl;
	my %mode = (
	  '<'  => O_RDONLY,
	  '+<' => O_RDWR,
	  '>'  => O_WRONLY | O_TRUNC   | O_CREAT,
	  '+>' => O_RDWR   | O_TRUNC   | O_CREAT,
	  '>>' => O_WRONLY | O_APPEND  | O_CREAT,
	  '+>>' => O_RDWR   | O_APPEND | O_CREAT,
	);

You get the numerical mode from the string representation *after*
IO::Handle::_open_mode_string() has had its hand in normalising it.

Besides... the PERMS you pass to this function, only has effect if your
provide a numerical mode. Even though it's documented... Surely that
can't be right?

The patched open() as I would propose it (warning: untested):

my %mode = (
  '<'  => O_RDONLY,
  '+<' => O_RDWR,
  '>'  => O_WRONLY | O_TRUNC   | O_CREAT,
  '+>' => O_RDWR   | O_TRUNC   | O_CREAT,
  '>>' => O_WRONLY | O_APPEND  | O_CREAT,
  '+>>' => O_RDWR   | O_APPEND | O_CREAT,
);

sub open {
    @_ >= 2 && @_ <= 4 
      or croak 'usage: $fh->open(FILENAME [,MODE [,PERMS]])';
    my ($fh, $file) = @_;
    if (@_ > 2) {
        my ($mode, $perms) = @_[2, 3];
        $mode =~ /^\d+$/
          or $mode = $mode{IO::Handle::_open_mode_string($mode)};
        defined $perms or $perms = 0666;
        return sysopen($fh, $file, $mode, $perms);
    }
    open($fh, $file);
}

-- 
	Bart.