Hello,

perlport says:

        truncate FILEHANDLE,LENGTH 
        truncate EXPR,LENGTH 

        ...

        If a FILEHANDLE is supplied, it must be writable and opened in
append mode (i.e., use open(FH, '>>filename') or
sysopen(FH,...,O_APPEND|O_RDWR). If a filename is supplied, it should not be
held open elsewhere. (Win32) 

        http://www.perldoc.com/perl5.8.0/pod/perlport.html

In my testing, truncate works properly on Win32 when the filehandle is
opened with *any* read-write mode, not just append.  I ran the test script
below on Windows 2000 on NTFS and FAT drives, and on Win98 on a FAT drive.
All read-write modes worked flawlessly with truncate.  I used v5.8.0
(activestate build 806) on win2k and v5.8.1 (build 807) on Win98.

The other bit about truncate($filename) requiring that the file not be
opened elsewhere is correct.

Anyhow... I'm sure the warning about modes is there for a reason, and so I'm
just asking if you all would check whether those reasons still apply with
Perl 5.8, and if they do, would you clarify in the FAQ under what conditions
append mode must be used on win32.

Thanks,
Zoltan



#!/usr/bin/perl -w
use strict;

print "Perl version is $^O\n";

my $file = 'truncate_test.bin';

my $mode;
foreach $mode ( '>', '>>', '+>>', '+>', '+<' ) {

        open( FILE, $mode, $file) || die $!;

        ( print FILE 'hello' ) || die $!;

        truncate( FILE, 2 ) || die $!;

        close(FILE) || die $!;

        if ((-s $file) != 2) { die "file was not truncated to 2 bytes"; }

        print "Success - truncate worked with mode $mode\n";

        }

use Fcntl;
foreach $mode ( O_RDWR, O_RDWR | O_APPEND ) {

        sysopen( FILE, $file, $mode ) || die $!;

        syswrite( FILE, 'hello' ) || die $!;

        truncate(FILE, 2 ) || die $!;

        close(FILE) || die $!;

        if ((-s $file) != 2) { die "file was not truncated to 2 bytes"; }

        print "Success - sysyopen truncate worked with mode $mode\n";
        }

unlink($file) || die $!;
#eof

Reply via email to