views:

112

answers:

1

My upload function looks like:

sub Upload_File{
my ($file, $mime, $description) = @_;
my $file_name   = param('filename');

my $data;

$file = UnTaint($file);

    if ($mime =~ /text/) {
            sysopen(VAULT, "$path/$file", O_RDWR | O_EXCL | O_CREAT | O_TEXT) or die "couldn't create $file for R/W: $!\n"; }
    else {
            sysopen(VAULT, "$path/$file", O_RDWR | O_EXCL | O_CREAT | O_BINARY) or die "couldn't create $file for R/W: $!\n";
    }

    my $upfh = \*VAULT;
    flock $upfh, 2;
    seek $upfh, 0, 0;
    select((select($upfh), $| = 1)[0]);
    while( sysread($file_name, $data, 8192) ) {
            syswrite($upfh, $data, 8192) or die "couldn't write $upfh: $!\n";
    }

    close $upfh; }

When I am using read and print with FastCGI upload script, files uploaded with corruptions (including simple text files), this is because perl uses buffered I/O. But when I use syswrite and sysread i.e. non-buffered I/O, as a result I get good text files, but binary files are corrupted anyway.

+1  A: 

I'm seeing some confusion regarding $file and $file_name. The latter is either wrongly named or wrongly used.

Further, this sounds to me like a binmode problem. You may want to call binmode on your input filehandle.

As a further hint, you could open your files as sysopen(my $upfh, .... And seek is buffered, so if you're using syswrite (I wouldn't) then you can better use sysseek.

Leon Timmermans
Thanks,i'm try to use sysseek, but it does not helps me.and yes $file and $file_name wrongly named, but works fine.after adding binmode(VAULT) in if-else statement, right after sysopen, there is no changes. some expirements show me, that text files corrupts too, when they are quite big. i add $CGI::POST_MAX=1024 * 10000, but it does not helps.