Jump to content

helices

Members
  • Posts

    10
  • Joined

  • Last visited

helices's Achievements

Newbie

Newbie (1/5)

0

Reputation

  1. For those who come here later, I have found a solution. I could not find a solution using alarms. Instead, my solution forks a 2nd process to time the 1st. The only problem I've not resolved is eliminating the annoying text "Terminated" from main script output ... #!/usr/bin/php <?php // GLOBALS $CHILD_PID = 0; $PID = getmypid(); $TIMEOUT = 5; // number of seconds to timeout echo "TIMER: {$TIMEOUT} seconds\n\n"; // Make sure program execution doesn't time out // If set to (0), no time limit is imposed set_time_limit(0); // Begin timer here set_timeout(); // Do system stuff here echo "Doing STUFF here\n\n"; extProg(); // End timer here clear_timeout($CHILD_PID); echo "STUFF is _COMPLETE_ here\n\n"; exit(0); // Stop timer function clear_timeout($CHILD_PID) { posix_kill($CHILD_PID, SIGTERM); } // Execute external program function extProg () { $ldir = 'abcdef'; $prog = "/usr/bin/lftp -e \"cd /_DIR_/;pwd;cls -lrt;\" -u '_ACCOUNT_,bogus' sftp://DOMAIN.com"; $sdir = 'uvwxyz'; $fd = array( 1 => array("pipe", "w"), // stdout 2 => array("pipe", "w"), // stderr ); $proc = proc_open($prog, $fd, $pipes, $ldir, null); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = explode("\n",stream_get_contents($pipes[2])); fclose($pipes[2]); proc_close($proc); $err = $stderr[0]; if ($sdir != '/') { $str = "cd ok, cwd={$sdir}"; if ($stderr[0] == $str) $err = $stderr[1]; } if ($err > '') return $err; return 0; } // Set timeout timer function set_timeout() { global $CHILD_PID; global $PID; global $TIMEOUT; $CHILD_PID = pcntl_fork(); if($CHILD_PID == 0) { sleep($TIMEOUT); posix_kill($PID, SIGTERM); echo "ERROR: extProg() stopped after {$TIMEOUT} seconds: "; exit(999); } } ?> Of course, I have "dummied up" the lftp connection parameters - suffice it to say that, with my real world parameters, this script throws an error, stops the lftp process and exits as I see fit Any ideas how to silence the errant text output? ~ Mike
  2. I have; but, I'm reading them again and not seeing anything jump out at me By "notes," are you referring to this? http://php.net/manual/en/function.proc-open.php#refsect1-function.proc-open-notes Or, User Contributed Notes: http://php.net/manual/en/function.proc-open.php#usernotes If the former, are you suggesting that I ought to use popen() instead of proc_open() ? If the latter, please, point me to the specific user note that you mean. Thank you.
  3. Is this better? #!/usr/bin/php <?php $count = 0; $interval = 1; ### $interval = 5; $max = 5; ### $max = 10; $time = 7; # $time = 20; ### $time = 900; $one = alarm_test(); echo "\n\tONE: {$one}\n\n"; $two = post_alarm(); echo "\n\tTWO: {$two}\n\n"; function post_alarm() { global $count, $interval, $time; $max = $time + 10; while ( $count < $max ) { $count += $interval; print $count."\n"; sleep($interval); } return($count); } function alarm_test() { global $count, $interval, $max, $time; declare(ticks=1); pcntl_signal(SIGALRM, "signal_handler"); pcntl_signal(SIGINT, "signal_handler"); pcntl_signal(SIGQUIT, "signal_handler"); pcntl_signal(SIGTERM, "signal_handler"); pcntl_alarm($time); # Execute time sensitive stuff HERE: while ( $count < $max ) { $count += $interval; print $count."\n"; sleep($interval); } # Any call to pcntl_alarm() will cancel any previously set alarm # If seconds is zero, no new alarm is created pcntl_alarm(0); echo "\n\tAlarm is RESET - We can do something else NOT time sensitive\n\n"; return($max); } function signal_handler($signal) { switch($signal) { case SIGTERM: echo "Caught SIGTERM\n"; exit; case SIGQUIT: echo "Caught SIGQUIT\n"; exit; case SIGINT: echo "Caught SIGINT\n"; exit; case SIGALRM: echo "\nCaught SIGALRM!\n"; echo "DO SOMETHING HERE ...\n\n"; exit; } } ?> function extProg ($array) { $ldir = $array['local_directory']; $prog = $array['prog']; $sdir = $array['remote_dir']; $fd = array( 1 => array("pipe", "w"), // stdout 2 => array("pipe", "w"), // stderr ); $proc = proc_open($prog, $fd, $pipes, $ldir, null); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = explode("\n",stream_get_contents($pipes[2])); fclose($pipes[2]); proc_close($proc); $err = $stderr[0]; if ($sdir != '/') { $str = "cd ok, cwd={$sdir}"; if ($stderr[0] == $str) $err = $stderr[1]; } if ($err > '') return $err; return 0; }
  4. OK, I'm sorry for being abrasive today. If I can find a code example that works without a "loop" to increment ticks, I can take it from there. I don't know why alarm in PHP doesn't work like it does in system and Perl. The following test script does what I want, except I must replace the while() loop with the function call to proc_open(): #!/usr/bin/php <?php $count = 0; $interval = 1; ### $interval = 5; $max = 5; ### $max = 10; $time = 7; # $time = 20; ### $time = 900; $one = alarm_test(); echo "\n\tONE: {$one}\n\n"; $two = post_alarm(); echo "\n\tTWO: {$two}\n\n"; function post_alarm() { global $count, $interval, $time; $max = $time + 10; while ( $count < $max ) { $count += $interval; print $count."\n"; sleep($interval); } return($count); } function alarm_test() { global $count, $interval, $max, $time; declare(ticks=1); pcntl_signal(SIGALRM, "signal_handler"); pcntl_signal(SIGINT, "signal_handler"); pcntl_signal(SIGQUIT, "signal_handler"); pcntl_signal(SIGTERM, "signal_handler"); pcntl_alarm($time); # Execute time sensitive stuff HERE: while ( $count < $max ) { $count += $interval; print $count."\n"; sleep($interval); } # Any call to pcntl_alarm() will cancel any previously set alarm # If seconds is zero, no new alarm is created pcntl_alarm(0); echo "\n\tAlarm is RESET - We can do something else NOT time sensitive\n\n"; return($max); } function signal_handler($signal) { switch($signal) { case SIGTERM: echo "Caught SIGTERM\n"; exit; case SIGQUIT: echo "Caught SIGQUIT\n"; exit; case SIGINT: echo "Caught SIGINT\n"; exit; case SIGALRM: echo "\nCaught SIGALRM!\n"; echo "DO SOMETHING HERE ...\n\n"; exit; } } ?> Following is the function that calls proc_open() from one of many scripts that have worked for more than 10,000 times, with the rare (less than 1 in 500 times) case of taking "too long:" function extProg ($array) { $ldir = $array['local_directory']; $prog = $array['prog']; $sdir = $array['remote_dir']; $fd = array( 1 => array("pipe", "w"), // stdout 2 => array("pipe", "w"), // stderr ); $proc = proc_open($prog, $fd, $pipes, $ldir, null); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = explode("\n",stream_get_contents($pipes[2])); fclose($pipes[2]); proc_close($proc); $err = $stderr[0]; if ($sdir != '/') { $str = "cd ok, cwd={$sdir}"; if ($stderr[0] == $str) $err = $stderr[1]; } if ($err > '') return $err; return 0; } Does this suffice for my code examples? Thank you. ~ Mike
  5. Suffice it to say that the 10,000 line script works 100% - except that sometimes (1 in 500 runs) that line of code hangs for >30 minutes I've been coding for more than 40 years and PHP for more than 10 years. My code works. The rare hangs are not due to faulty code; rather, they are due to system problems, mostly on remote systems, over which I have 0 control All I am asking for is an example of a multi-tasked timer that can be set immediately prior to the function/subroutine call that includes: proc_open() - so that after X time, I can do something else, other than what that proc_open() is doing. Since "my" code includes PCI related security routines and the bulk of this has zero to do with this particular challenge, I will not be be posting: "ALL of your code" Is this too difficult for you? If so, please, accept my humblest apologies ... ~ Mike
  6. As I posted, this IS my code: $proc = proc_open($prog, $fd, $pipes, $ldir, null); One specific case, $prog is an lftp session to a remote server, getting or putting files Sometimes, unknown problem on that remote server leave this proc_open() call hanging. In these cases, I want an alarm-like process to do something after (30) minutes, such as write a message to STDERR and exit the script. What else do you need to know?
  7. It's your first: "waiting on an external process to complete" This works, but sometimes exceeds (30) minutes: $proc = proc_open($prog, $fd, $pipes, $ldir, null); I have a test script using: pcntl_alarm($time); before this: while ( $count < $max ) { ... } which works as desired It took me too long to realize that I needed to proceed pcntl_alarm() with this: declare(ticks=1); or it does not work :-( Does pcntl_alarm() require ticks? Why isn't this documented on the pcntl_alarm() manual page? When I do the $proc = ... thing - even with ticks - the alarm is never caught In the shell or even Perl, alarms work as I expect. What am I missing?
  8. I execute a system call via proc_open() that usually completes in less than one minute Sometimes, it hangs for many hours I want to exit this parent script after thirty (30) minutes with the error description on STDERR and I also want that system call process killed at this point Although, a test script using ticks and pcntl_alarm(1800) works using a while() loop, this does NOT work with my production system call Since ticks is documented as deprecated, I want to find a solution that does not use ticks What am I missing? Please, advise. Thank you ~ Mike
  9. Thank you; but, that's not my problem here. The example installation is looking here: /usr/local/php-5.2.17/lib/php.ini HOW can I get that instance to always look here: /etc/php.ini ??? NO, I cannot do: php -c path|file -NOR- php --php-ini path|file Yes, I can make a symbolic link; but, I'm looking to understand HOW this example installation knows to look here: /usr/local/php-5.2.17/lib/php.ini When I understand why it's looking there, then I will know what to do in other cases. The manual appears to be incorrect when it states: php.ini is searched for in these locations (in order): SAPI module specific location (PHPIniDir directive in Apache 2, -c command line option in CGI and CLI, php_ini parameter in NSAPI, PHP_INI_PATH environment variable in THTTPD) The PHPRC environment variable. Before PHP 5.2.0, this was checked after the registry key mentioned below. As of PHP 5.2.0, the location of the php.ini file can be set for different versions of PHP. The following registry keys are examined in order: [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y.z], [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y] and [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x], where x, y and z mean the PHP major, minor and release versions. If there is a value for IniFilePath in any of these keys, the first one found will be used as the location of the php.ini (Windows only). [HKEY_LOCAL_MACHINE\SOFTWARE\PHP], value of IniFilePath (Windows only). Current working directory (except CLI). The web server's directory (for SAPI modules), or directory of PHP (otherwise in Windows). Windows directory (C:\windows or C:\winnt) (for Windows), or --with-config-file-path compile time option.
  10. I have inherited ( 8 ) servers on an intranet using various versions of php as main programming language. Most of these are not web servers. I've been tasked to consolidate and standardize on one (1) php.ini configuration file to be used on all ( 8 ) servers Some of these use odd locations for php.ini For example, a Solaris 10 host uses this configuration file: /usr/local/php-5.2.17/lib/php.ini # /usr/bin/php --info | grep -i php\.ini Configuration File (php.ini) Path => /usr/local/php-5.2.17/lib Loaded Configuration File => /usr/local/php-5.2.17/lib/php.ini # php-config | grep -i ini # php-config | grep -i with-config-file-path [ NO compile time options returned ... ] NONE of the user accounts running php have PHPRC set. Current working directory is whatever directory the user is in at execution time One thing that I need to do is get ALL of these servers using /etc/php.ini - even if that is a symbolic link How can I accomplish this standardization of /etc/php.ini? Please, advise. Thank you.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.