The upload() function's return is meant to be used as a filehandle (a re-writing of your code):
in reply to CGI.pm's upload gives local filename, not file itself
use CGI qw(:standard);
# (update: in your code you didn't import anything?!
# I guess that you didn't show us the real code then...
# (copy-and-paste if your friend.) (I'm referring
# to the 'use CGI' line, of course.))
my $fh = upload('file');
open TEMP, ">temp.jpg" or die "error opening temp.jpg for writing: $!\
binmode TEMP; # very important on Windows-based machines
# this block is so the assignment to $/
# will not effect the rest of the script
local $/ = \1024; # tell <...> to read in 1024-byte chunks.
print TEMP $_ while <$fh>;
close TEMP or warn "error closing temp.jpg: $!\n";
(The use of strict and warnings is strongly reccommended.)