in reply to upload filehandle expiration
CGI.pm will handle the file upload for you. It will check for the max allowed filesize which you can also set ( see Ovid's great CGI-course for that). It will if the file does not exceed the allowed size put it to a tmp directory from where you don't grab it but rather get it passed from CGI.pm.
Inside your script you are creating ONE filehandle $fh. It is only referenced to inside the scope of your foreach loop. With every run it gets a new upload file associated with. Once you leave your foreach it is out of scope , the $fh is not referenced anymore and will be cleaned up by perls garbage collection.
Have a nice day
All decision is left to your taste