Receiving closed filehandle warning

Please support our Perl advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Aug 2005
Posts: 902
Reputation: chrisbliss18 is an unknown quantity at this point 
Solved Threads: 23
chrisbliss18's Avatar
chrisbliss18 chrisbliss18 is offline Offline
Posting Shark

Receiving closed filehandle warning

 
0
  #1
Jan 7th, 2008
I have a situation where a file upload program that has been running without any problems for months now suddenly uploads completely empty files. When I turn on warnings (perl -w), I get a message like the following:
  1. FATAL WARNING: read() on closed filehandle fh00001license.txt at CDownloadEditor.pm line 293.
Here is my main problem. I had this happen on a different server about a month ago. After a full day of scratching my head, delving back into the apache config, making slight modifications, looking at up2date logs, etc, I gave up for the day. When I tried using the program the next morning, it worked. So, I had made many different changes and rewritten the code many times with no change, it still did not work when I left, and it worked when I came back (no one else had access BTW). To further complicate things, my up2date logs showed that nothing changed overnight.

I thought of it as a weird fluke and shrugged it off, now it is happening on a different server. Both of these two servers are fairly small and the problem only affected one client. Now I'm concerned that this problem might occur on one of our critical servers that hosts many clients.

Another piece of important information is that while both the program that failed and then worked and this current program are programs to upload files, they are completely different versions of code that work differently. They don't even share any custom libraries in common.

The subroutine I call is as follows:
  1. sub uploadFile
  2. {
  3. my $self = shift;
  4. my %FORM = %{$self->{FORM}};
  5. my %sysvars = %{$self->{GVARS}};
  6.  
  7. my ($variableName, $variableID);
  8.  
  9. if(@_)
  10. {
  11. $variableName = shift;
  12. $variableID = shift;
  13. }
  14.  
  15. return if($FORM{$variableName} eq '');
  16.  
  17. my $extension = $1 if($FORM{$variableName} =~ /\.([^\.]+)$/);
  18. my $fileHandle = $FORM{$variableName};
  19. my $filename = $variableID . $variableName . '.' . lc($extension);
  20. my $path = "$sysvars{MODFILEPATH}/$sysvars{FILE}";
  21.  
  22. if($filename =~ /([^\/\\]+)$/)
  23. {
  24. $filename = $1;
  25. }
  26. else
  27. {
  28. return "error";
  29. }
  30.  
  31. if (!(-d "$path/"))
  32. {
  33. mkdir("$path/", 0777);
  34. }
  35. if(-f "$path/$filename")
  36. {
  37. unlink("$path/$filename");
  38. }
  39.  
  40. if(!(open(IMAGEFILE, ">$path/$filename")))
  41. {
  42. if($FORM{'SCRIPTERROR-FILEUPLOAD'} eq '')
  43. {
  44. $self->{FORM}->{'SCRIPTERROR-FILEUPLOAD'} = 1;
  45.  
  46. $self->setErrorMessage("File did not upload correctly. The system administrator has been notified of this issue.<br>Please try editing the record later to upload the file.");
  47.  
  48. $self->sendTechnicalInformation("File permissions issue.");
  49. }
  50.  
  51. return;
  52. }
  53.  
  54. my $bytesRead;
  55. my $buffer;
  56.  
  57.  
  58. while(my $bytes = read($fileHandle, $buffer, 2096))
  59. {
  60. $bytesRead += $bytes;
  61. binmode IMAGEFILE;
  62. print IMAGEFILE $buffer;
  63. }
  64.  
  65. close($fileHandle);
  66. close(IMAGEFILE);
  67.  
  68. chmod (0777, "$path/$filename");
  69.  
  70. $self->{FORM}->{$variableName} = "$sysvars{MODFILEURL}/$sysvars{FILE}/$filename";
  71.  
  72. $self->doSQLUpdate('', "ID='$variableID'");
  73.  
  74. $self->setSuccessMessage("Upload Successful: $bytesRead bytes read.");
  75. }
No other code before this call attempts to open or close any file handles.

This subroutine is called by a line such as:
  1. $self->uploadFile('file', $id) if($FORM{'file'});
Note that the %FORM hash contains variables passed in from the CGI module. The code that handles that is as follows:
  1. my $query = new CGI;
  2.  
  3. my $sql = do_sql->new;
  4. $sql->connect;
  5.  
  6. foreach my $key (sort {$a <=> $b} $query->param())
  7. {
  8. my $value = $query->param($key);
  9.  
  10. $self->{FORM}->{$key} = $value;
  11. }
If you have any advice to offer, please share it. This has baffled me long enough. Thank you.
Did we help you? Did we miss the point entirely? Update your thread and let us know.
Don't like the answers you are getting?
Did you try searching?
Clean up and optimize Windows 2000/XP
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 898
Reputation: KevinADC has a spectacular aura about KevinADC has a spectacular aura about 
Solved Threads: 67
KevinADC's Avatar
KevinADC KevinADC is offline Offline
Practically a Posting Shark

Re: Receiving closed filehandle warning

 
0
  #2
Jan 7th, 2008
Another piece of important information is that while both the program that failed and then worked and this current program are programs to upload files, they are completely different versions of code that work differently. They don't even share any custom libraries in common.
Almost sounds like someone is hitting the "stop" button on the browser while uploading a file. Maybe someone else will have an idea to help you, but I am baffled by the problem you have described.
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 902
Reputation: chrisbliss18 is an unknown quantity at this point 
Solved Threads: 23
chrisbliss18's Avatar
chrisbliss18 chrisbliss18 is offline Offline
Posting Shark

Re: Receiving closed filehandle warning

 
0
  #3
Jan 8th, 2008
Thanks for the response KevinADC. Unfortunately, it's nothing as simple as that. I run these tests myself using a variety of different browsers and with both small and large files with the same results. The Apache error logs don't report any problems either whereas they would typically report a short send by a connection failure or stop button.
Did we help you? Did we miss the point entirely? Update your thread and let us know.
Don't like the answers you are getting?
Did you try searching?
Clean up and optimize Windows 2000/XP
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 898
Reputation: KevinADC has a spectacular aura about KevinADC has a spectacular aura about 
Solved Threads: 67
KevinADC's Avatar
KevinADC KevinADC is offline Offline
Practically a Posting Shark

Re: Receiving closed filehandle warning

 
0
  #4
Jan 8th, 2008
just for sanity sake I would add in some error handling for any sytem functions, like these:

  1. if (!(-d "$path/"))
  2. {
  3. mkdir("$path/", 0777) or some error handling here;
  4. }
  5. if(-f "$path/$filename")
  6. {
  7. unlink("$path/$filename") or some error handling here;
  8. }

make sure everything else is working so you can for sure track it down to the read() function being the real source of the problem, or at least the point where the problem occurs. Why the filehandle is closed is a mystery at this point. It worked, nothing got changed, now it does not work.... thats possible but leads to more fundamental questions, like is the server/computer going bad? Was new software installed or ugraded? It does not sound like a perl problem though.
Reply With Quote Quick reply to this message  
Join Date: Sep 2007
Posts: 176
Reputation: trudge is an unknown quantity at this point 
Solved Threads: 20
trudge trudge is offline Offline
Junior Poster

Re: Receiving closed filehandle warning

 
0
  #5
Jan 8th, 2008
A couple things. First, is it wise to have the binmode within the loop
  1. while(my $bytes = read($fileHandle, $buffer, 2096))
  2. {
  3. $bytesRead += $bytes;
  4. binmode IMAGEFILE;
  5. print IMAGEFILE $buffer;
  6. }
I've always called it first after opening the file handle, but before operating on the file.

Second, the error refers to a module 'CDownloadEditor.pm line 293'. Is this code part of that module, or does the script call that module. What is the code around line 293, or is that line the call to this subroutine?
Amer Neely - Web Mechanic
"Others make web sites. We make web sites work!"
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 902
Reputation: chrisbliss18 is an unknown quantity at this point 
Solved Threads: 23
chrisbliss18's Avatar
chrisbliss18 chrisbliss18 is offline Offline
Posting Shark

Re: Receiving closed filehandle warning

 
0
  #6
Jan 8th, 2008
Originally Posted by trudge View Post
A couple things. First, is it wise to have the binmode within the loop
  1. while(my $bytes = read($fileHandle, $buffer, 2096))
  2. {
  3. $bytesRead += $bytes;
  4. binmode IMAGEFILE;
  5. print IMAGEFILE $buffer;
  6. }
I've always called it first after opening the file handle, but before operating on the file.

Second, the error refers to a module 'CDownloadEditor.pm line 293'. Is this code part of that module, or does the script call that module. What is the code around line 293, or is that line the call to this subroutine?
Good point on the binmode in the loop. I've fixed that in other code, but it never caused any problems. That section of code doesn't matter however as the read() fails before the loop even executes.

As for CDownloadEditor.pm, that is the file that I have the large portion of code taken from. Line 293 is the while loop with the read() call (the beginning of your quoted code).
Last edited by chrisbliss18; Jan 8th, 2008 at 2:09 pm.
Did we help you? Did we miss the point entirely? Update your thread and let us know.
Don't like the answers you are getting?
Did you try searching?
Clean up and optimize Windows 2000/XP
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 902
Reputation: chrisbliss18 is an unknown quantity at this point 
Solved Threads: 23
chrisbliss18's Avatar
chrisbliss18 chrisbliss18 is offline Offline
Posting Shark

Re: Receiving closed filehandle warning

 
0
  #7
Jan 8th, 2008
After bringing in an expert I know, a solution was found. The problem is that I use the CGI package to pull in all the form variable data. I let my CGI object variable go out of scope. Apparently, something either with my Perl packages or my system caused the CGI object to be garbage collected before my program could use the data.

After putting a copy of the object reference in a variable that had a top-level scope, the problem went away.

Thank you very much for your help KevinADC and trudge.
Did we help you? Did we miss the point entirely? Update your thread and let us know.
Don't like the answers you are getting?
Did you try searching?
Clean up and optimize Windows 2000/XP
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 898
Reputation: KevinADC has a spectacular aura about KevinADC has a spectacular aura about 
Solved Threads: 67
KevinADC's Avatar
KevinADC KevinADC is offline Offline
Practically a Posting Shark

Re: Receiving closed filehandle warning

 
0
  #8
Jan 9th, 2008
ahh, that will be a good thing to remember for future reference.
Reply With Quote Quick reply to this message  
Join Date: Sep 2007
Posts: 176
Reputation: trudge is an unknown quantity at this point 
Solved Threads: 20
trudge trudge is offline Offline
Junior Poster

Re: Receiving closed filehandle warning

 
0
  #9
Jan 9th, 2008
Just for my own curiosity, do you have
  1. use strict;
  2. use warnings;
at the top of your script? It may have caught something which would have solved this faster. It's always a good idea to include both those statements on production code.

ps. Please mark this as 'SOLVED' by editing your first post in this thread.
Amer Neely - Web Mechanic
"Others make web sites. We make web sites work!"
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 902
Reputation: chrisbliss18 is an unknown quantity at this point 
Solved Threads: 23
chrisbliss18's Avatar
chrisbliss18 chrisbliss18 is offline Offline
Posting Shark

Re: Receiving closed filehandle warning

 
0
  #10
Jan 10th, 2008
Originally Posted by trudge View Post
Just for my own curiosity, do you have
  1. use strict;
  2. use warnings;
at the top of your script? It may have caught something which would have solved this faster. It's always a good idea to include both those statements on production code.

ps. Please mark this as 'SOLVED' by editing your first post in this thread.
I did originally have "use strict". I added warnings when the problem occurred. The warning told me that I was trying to read a closed file handle. Helpful information, but that did not get me pointed in the right direction immediately.

BTW... I don't think it's possible to edit posts. I didn't know we could mark threads solved now, so after a bit of looking around I found a little link at the bottom of the page above the quick reply box for marking the thread solved. A very unintuitive and hard to find link if you ask me.
Did we help you? Did we miss the point entirely? Update your thread and let us know.
Don't like the answers you are getting?
Did you try searching?
Clean up and optimize Windows 2000/XP
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Other Threads in the Perl Forum
Thread Tools Search this Thread



Tag cloud for Perl
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC