ID:               32491
 Updated by:       [EMAIL PROTECTED]
 Reported By:      Oscar dot Castillo at jpl dot nasa dot gov
-Status:           Open
+Status:           Closed
 Bug Type:         Feature/Change Request
 Operating System: Solaris 9
 PHP Version:      5CVS-2005-03-31
 New Comment:

This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

For file upload the fd problem is fixed - but it can still happen with
other stdio functions: php exec() which uses stdio popen()


Previous Comments:
------------------------------------------------------------------------

[2005-03-31 19:47:24] Oscar dot Castillo at jpl dot nasa dot gov

I have 3 web server environments setup with the same version of PHP, a
development environment, a test environment and a production
environment. Your description of the common Solaris /iPlanet problem
explains why the same PHP script works well in the development and test
environment, but not the production environment. I do have Java enabled
on all 3 web server environments, but the only difference is that our
production is obviously much more heavily utilized than the test and
development environment. I thank you very much for the explanation.

Since Java is required on our web servers, I obviously cannot disable
Java. I will try loading the fastcgi API. I'll keep you posted.

------------------------------------------------------------------------

[2005-03-31 11:17:11] [EMAIL PROTECTED]

Again the old STDIO problem: There are some places in PHP where the C
library stdio functions are used instead of posix io (popen in all
excute functions/sendmail functions, uploading of temporary files, some
3rd party extensions). Under Solaris with the AT&T libc stdio is limited
to 255 file descriptors, if the current posix file descriptor gets
larger than 255 all further fopens or fdopens fail because the field in
the FILE* struct is a unsigned char. Using Posix IO has no limit here
(descriptor is int).
There are 2 solutions:
a) limiting the accepting threads in sunone/iplanet and disabling java
in webserver completely (java is very descriptor intensive ->
descriptors for PHP get > 255)
b) using PHP as CGI/FastCGI (look for Sun PHP enabler at zend.com) or
my CGI enabler: http://www.thetaphi.de/php-ressources/

Changing this in PHP is a heavy task, the zend engine itsself is safe
since 4.3.3, other parts should be changed in the future to POSIX IO.

This is a Solaris problem which gets important in a multithreaded and
heavy file descriptor using webserver like sunone/iplanet

------------------------------------------------------------------------

[2005-03-29 21:55:27] Oscar dot Castillo at jpl dot nasa dot gov

Description:
------------
I am using iPlanet 6.0 SP5, Zend 2.5.7 and PHP 5.0.3 on a 64 bit
Solaris 9 SunFire V880 (4x4GHz CPU, 8Gb RAM). I have a problem with an
HTTP POST command that attempts to upload a file onto the web server
and a consistent "File upload error - unable to create a temporary file
in Unknown on line 0" error message appears in the error logs. The
upload_tmp_dir directory is set to /tmp. The error message disappears
with a web server daemon reset (stop/start the web server daemon), but
the error begins to occur within 2 to 24 hours again. When the errors
occur, the /tmp directory begins to accumulate with php[web_server_pid]
files that are zero bytes in size. My upload_max_filesize parameter is
configured to 2Mb, however the uploaded files are never above 50kb.
I've tried many suggested fixes from the php.net bug reports area, but
to no avail. Thanks in advance for your help!

Reproduce code:
---------------
<?php
$debug_level = 2;               // 0 = no debug; 10 = most debug
if ($debug_level > 9) { phpinfo(); }
//
// Configurable variables
//
  $BaseDir = './';
  $LogFileName = $BaseDir . "RTIU_translator.log";
  $SCLK_SCET_Dir = "/afs/jpl/group/casops/dom/data/main/sclkscet/";  //
placed in executed shell script
  $UploadDir = $BaseDir . "Temp/" ;             //      Where the posted files 
are
placed
  $TransferDir = $BaseDir . "Xfer/";    //  Where the tar file for the
translator is created

//
// Verify resources are available
//

$LogFile = fopen( $LogFileName,'a');
if (! $LogFile)
{ print("Logging is disabled, please save all displayed messages if
help is needed from IO support<br>");
}

// Verify UPLOAD directory
if (!file_exists($UploadDir))
{ if ($LogFile)
  { $TmpStr = sprintf("%s VERIFY Upload directory does not exist\n",
                                          gmdate("Y-m-d H:i:s") );
//                      strftime("%Y-%m-%d %T"));
    fwrite($LogFile, $TmpStr);
  }
  if(!mkdir($UploadDir,0774))
  { DisplayError("Could not create Upload directory",0);
    return;
  }
}
// Verify TRANSFER directory
if (!file_exists($TransferDir))
{ if ($LogFile)
  { $TmpStr = sprintf("%s VERIFY Transfer directory does not exist\n",
                                          gmdate("Y-m-d H:i:s") );
//                      strftime("%Y-%m-%d %T"));
    fwrite($LogFile, $TmpStr);
  }
  print( "Missing Transfer Directory: $TransferDir <br>");
  if (!mkdir($TransferDir,0774))
  { DisplayError("Could not create Transfer directory",0);
    return;
  }
}

//
// Capture form values
//

$BaseName = escapeshellcmd($_POST['BaseName']);
$SequenceID = $_POST['SequenceID'];
$SCLK_SCET_File = $_POST['SCLK_SCET_File'];
$StartTimeUTC = $_POST['StartTimeUTC'];
$StopTimeUTC = $_POST['StopTimeUTC'];
$InputType = $_POST['input_type'];                      // SASF or PRT
$OutputType = $_POST['output_type'];            // SEQ or IEB
$UserFileName = $_FILES['UploadFile']['name'];
$StartALF = $_POST['StartALF'];                         // 0 <= ?
$ALF_Partition = $_POST['ALF_Partition'];       // DEFAULT or NON_DEFAULT
$ALF_Step = $_POST['ALF_Step'];                         // 4 or 8

$CAS_User = $_SERVER['REMOTE_USER'];
$HostSource = $_SERVER['REMOTE_HOST'];

//
//  Debug stuff (POST data)
//
if ($debug_level > 3)
{ print( "Upload Directory: $UploadDir <br>");
  print( "SCLK/SCET Directory: $SCLK_SCET_Dir <br>");

  if ($debug_level > 8)
  { print ("<pre>");
    var_dump($_FILES);

    var_dump($_POST);
    print ("</pre>");
  }
  print( "Input Type: $InputType <br>");
  print( "Basename: $BaseName <br>");
  print( "Upload File: $UserFileName <br>");
  print( "Sequence ID: $SequenceID <br>");
  print( "SCLK/SCET File: $SCLK_SCET_File <br>");
  print( "Start UTC: $StartTimeUTC <br>");
  print( "Stop UTC: $StopTimeUTC <br>");

  print( "Output Type: $OutputType <br>");
  print( "Start ALF: $StartALF <br>");
  print( "Partition: $ALF_Partition <br>");
  print( "ALF Step: $ALF_Step <br>");
}

//
// Verify parameter values
//
print("<H2>Processing an $InputType upload</H2><br>");

//
//  Log an attempted posting (user & host)
//
if ($LogFile)
{ $TmpStr = sprintf("%s REQUEST (%s) %s from %s\n",
//                    strftime("%Y-%m-%d %T"), $BaseName, $CAS_User,
$HostSource);
                    gmdate("Y-m-d H:i:s"), $BaseName, $CAS_User,
$HostSource);
  fwrite($LogFile, $TmpStr);
}
  
// Check Basename
if (strlen($BaseName) == 0)
{ DisplayError("Basename must be specified to translate a
sequence",0);
  return;
} else
{ if (strlen($BaseName) != 6)
  { DisplayError("Basename invalid length: '$BaseName'",
                 "Must be 6 alpha-numeric characters");
    return;
  }
  if
(strspn($BaseName,"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
!= 6)
  { DisplayError("Basename invalid character(s): '$BaseName'",
                 "Must be 6 alpha-numeric characters");
    return;
  }
}
if (is_file("$TransferDir/$BaseName.tar") ||
is_dir("$TransferDir/$BaseName"))
{ DisplayError("The specified basename has been previously used",
               "Please select a different name: $BaseName");
  return;
}

// Check for uploaded file
if ($_FILES['UploadFile']['error'] != UPLOAD_ERR_OK)
{ $TmpStr = $_FILES['UploadFile']['name'];
  DisplayError("Error uploading sequence file", "$TmpStr");
  if ($debug_level > 1)
  { var_dump($_FILES);
    var_dump($_POST);
  }
  return;
}

// Verify SASF Parameters
if ($InputType == "SASF")
{ print("<H3>Verifying parameters for SASF processing</H3>");
  //  Start Times (only if SASF input)
  if (($StartUTC=Verify_UTC($StartTimeUTC,"Start Time")))
  { if (($StopUTC=Verify_UTC($StopTimeUTC,"Stop Time")))
    { if ($StopUTC <= $StartUTC)
      { DisplayError("'Stop Time' not later than 'Start Time'",
                     "Start: $StartTimeUTC<br>Stop: $StopTimeUTC");
        return;
      }
    } else      // Bad Stop Time
    { return;
    }
  } else        // Bad Start Time
  { return;
  }
} else          // InputType is PRT
{
}
//
// Build translation script
//
  $UploadFile = $UploadDir . "/" . $UserFileName;
  if (move_uploaded_file($_FILES['UploadFile']['tmp_name'],
$UploadFile))
  { // print ("Uploaded the $InputType file as $UploadFile<br>");
  } else
  { DisplayError("Could not get uploaded file: '$UserFileName'",0);
    if ($debug_level > 1)
    { var_dump($_FILES);
      var_dump($_POST);
    }
   return;
  }

  $ScriptFile = "$UploadDir/$BaseName.csh";
  $FileHandle = fopen($ScriptFile,"wb");
  if (! $FileHandle)
  { DisplayError("Could not create script file", 0);
    return;
  }
  fwrite($FileHandle,"#!/bin/csh\n");
  fwrite($FileHandle,"#\n");
  fwrite($FileHandle,"# Script is passed the two programs to be used as
parameters.\n");
  fwrite($FileHandle,"# The script is started with the working
directory containing\n");
  fwrite($FileHandle,"# and the uploaded user file (SASF or
PRTSEQ)\n\n");
  
  $PrtseqFile = $BaseName . "prtseq";
  if ($InputType == "SASF")
  { fwrite($FileHandle,"\$1 $UserFileName $SequenceID $BaseName
$SCLK_SCET_Dir/$SCLK_SCET_File $StartTimeUTC $StopTimeUTC\n");
  } else
  { fwrite($FileHandle,"cp $UserFileName $PrtseqFile\n");
  }
  fwrite($FileHandle,"# Include error check\n\n");
  
  if ($OutputType == "IEB")
  { fwrite($FileHandle,"\$2 $BaseName $StartALF $ALF_Partition
$ALF_Step < $PrtseqFile > $BaseName.seq\n");
  } else
  { fwrite($FileHandle,"\$2 $BaseName < $PrtseqFile >
$BaseName.seq\n");
  }
  fwrite($FileHandle,"# Include error check\n");
  fwrite($FileHandle,"\n# Calling script is responsible for moving
tar.gz to the download directory\n");
  fclose($FileHandle);                                                  // End 
of ScriptFile
  
  if ($debug_level > 4)
  { print ("<pre>\n\nScript File Commands ...\n\n");
    readfile($ScriptFile);
    print ("</pre>");
  }
  
  $TargetDir = $TransferDir . '/' . $BaseName;
  $BuildCmd = "mkdir -p $TargetDir";
  $CmdOutput = system($BuildCmd,$ReturnValue);
  if ($ReturnValue != 0)
  { DisplayError("ERROR making workspace for '$BaseName'","Error:
'$ReturnValue'");
    return;
  }

  $BuildCmd = "mv $ScriptFile $UploadFile $TargetDir";
  $CmdOutput = system($BuildCmd,$ReturnValue);
  if ($ReturnValue != 0)
  { DisplayError("ERROR moving '$UserFileName' to workspace","Error:
'$ReturnValue'");
    return;
  }

  $BuildCmd = "(cd $TransferDir; tar -cf $BaseName.tar $BaseName)";
  $CmdOutput = system($BuildCmd,$ReturnValue);
  if ($ReturnValue != 0)
  { DisplayError("ERROR transfering '$BaseName' package","Error:
'$ReturnValue'");
    return;
  }

  print ("<H3>Upload successfully completed</H3>");
  print ("<p>");
  print ("Processing will begin shortly");
  print ("</p><p>");
  print ("Please check back in a few minutes on the download tab to get
");
  print ("the translated sequence.<br>It will be called
'$BaseName.tar.gz'");
  print ("</p>");

  //
  //  Log successful upload
  //
  if ( $LogFile )
  { $TmpStr = sprintf("%s SUBMIT (%s) by %s successfully\n",
//                      strftime("%Y-%m-%d %T"), $BaseName, $CAS_User
);
                      gmdate("Y-m-d H:i:s"), $BaseName, $CAS_User );
    fwrite($LogFile,$TmpStr);
    fclose( $LogFile );
  }

  return;

//////
//  Verify_UTC function
//////
function Verify_UTC ( &$Time, $FieldName )
{
  $Status = sscanf($Time,"%d-%dT%d:%d:%d",$Year,$Day,$Hour,$Min,$Sec);
  if ($Status != 5)
  { 
    DisplayError ("Could not parse $FieldName: '$Time'",
                  "Must be in the form: 'yyyy-dddThh:mm:ss.mmm'");
    return 0;
  }

  $GMT_Time = mktime($Hour,$Min,$Sec,1,$Day,$Year);
  $CalcTime = strftime("%Y-%jT%T.000",$GMT_Time);

  if (strncmp($CalcTime,$Time,(strlen($CalcTime)-4)) == 0)
  { $Time = $CalcTime;
    return $GMT_Time;
  } else
  { DisplayError ("$FieldName interpreted as invalid: '$Time'",0);
    return 0;
  }
}

//////
//  DisplayError function
//////
function DisplayError( $ErrorMsg, $Ancillary )
{ global $LogFile, $CAS_User, $BaseName;

  print("<br><big> *** Processing Error ***</big><br>");
  print("$ErrorMsg<br>");
  if ($Ancillary != NULL)
  { print("<br>$Ancillary<br>");
  }
  
  //
  //  Log error in post (user and reason)
  //
  if ( $LogFile )
  { $TmpStr = sprintf("%s ERROR (%s) %s [%s]\n",
//                      strftime("%Y-%m-%d %T"), $BaseName, $ErrorMsg
);
                                          gmdate("Y-m-d H:i:s"), $BaseName, 
$ErrorMsg, $Ancillary );
    fwrite($LogFile,$TmpStr);
    fclose( $LogFile );
  }

  return;
}
?>

Expected result:
----------------
The uploaded file is transfered from a client machine onto the web
server's local filesystem structure.

Actual result:
--------------
PHP Warning: File upload error - unable to create a temporary file in
Unknown on line 0


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=32491&edit=1

Reply via email to