space has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I am start to learn CGI Program.

When I execute the following coding I get the following Error Message:

Can't use an undefined value as a symbol reference at C:/Apache2/cgi-b +in/de.cgi line 50.

Please guide where I made mistake

HTML File Contains

<html> <body> <form action="/cgi-bin/de.cgi" method="post" enctype="multipart/form-d +ata"> <p>Please Select a file to upload:</p> <input type="file" name="file"><br><br> <input type="text" name="filename"><br><br><br> <input type="submit"> </form> </body></html>

CGI File Contains

#!d:/perl/bin/perl use strict; use CGI; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use Fcntl qw( :DEFAULT :flock ); use constant UPLOAD_DIR => 'c:/uploads'; use constant BUFFER_SIZE => 16_384; use constant MAX_FILE_SIZE => 1_048_576; # Limit each upload to + 1 MB use constant MAX_DIR_SIZE => 100 * 1_048_576; # Limit total uploads +to 100 MB use constant MAX_OPEN_TRIES => 100; $CGI::DISABLE_UPLOADS = 0; $CGI::POST_MAX = MAX_FILE_SIZE; my $q = new CGI; $q->cgi_error and error( $q, "Error transferring file: " . $q->cgi_err +or ); my $file = $q->param( "file" ) || error( $q, "No file receive +d." ); my $filename = $q->param( "filename" ) || error( $q, "No filename ent +ered." ); my $fh = $q->upload( $file ); my $buffer = ""; if ( dir_size( UPLOAD_DIR ) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) { error( $q, "Upload directory is full." ); } # Allow letters, digits, periods, underscores, dashes # Convert anything else to an underscore $filename =~ s/[^\w.-]/_/g; if ( $filename =~ /^(\w[\w.-]*)/ ) { $filename = $1; } else { error( $q, "Invalid file name; files must start with a letter or n +umber." ); } # Open output file, making sure the name is unique until ( sysopen OUTPUT, UPLOAD_DIR . $filename, O_CREAT | O_EXCL ) { $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e; $1 >= MAX_OPEN_TRIES and error( $q, "Unable to save your file." ); } binmode $fh; binmode OUTPUT; # Write contents to output file while ( read( $fh, $buffer, BUFFER_SIZE ) ) { print OUTPUT $buffer; } close OUTPUT; sub dir_size { my $dir = shift; my $dir_size = 0; # Loop through files and sum the sizes; doesn't descend down subdi +rs opendir DIR, $dir or die "Unable to open $dir: $!"; while ( readdir DIR ) { $dir_size += -s "$dir/$_"; } return $dir_size; } sub error { my( $q, $reason ) = @_; print $q->header( "text/html" ), $q->start_html( "Error" ), $q->h1( "Error" ), $q->p( "Your upload was not procesed because the following e +rror ", "occured: " ), $q->p( $q->i( $reason ) ), $q->end_html; exit; }

Replies are listed 'Best First'.
Re: CGI Error
by davidrw (Prior) on Sep 27, 2005 at 12:52 UTC
    I think if you change:
    my $fh = $q->upload( $file );
    to:
    my $fh = $q->upload( 'file' );
    You should be good ... For reference, here's a very quick and dirty (but working) simple upload form example:
Re: CGI Error
by izut (Chaplain) on Sep 27, 2005 at 11:11 UTC

    Change, in the line 50, OUTPUT by STDOUT.

    Update: Misread question.

    It seems that $fh is not defined when you use it in open OUTPUT $buffer, check it. The code below reproduces the error:

    use Fcntl qw(:DEFAULT :flock); sysopen(OUTPUT, "output.bin", O_CREAT|O_EXCL|O_WRONLY) or die $!; binmode OUTPUT; while (read(my $fh, my $buffer, 4096)) { print OUTPUT $buffer; } close OUTPUT or die $!;


    Igor S. Lopes - izut
    surrender to perl. your code, your rules.

      Also there are an error in this code: my $fh = $q->upload( $file ); It should be like this (according to CGI.pm): my $fh = $q->upload( 'my_upload_field_from_form' );

      From CGI.pm:

      To be safe, use the upload() function (new in version 2.47). When called with the name of an upload field, upload() returns a filehandle, or undef if the parameter is not a valid filehandle.
      $fh = upload("uploaded_file"); while (<$fh>) { print; }


      Igor S. Lopes - izut
      surrender to perl. your code, your rules.