--- includes/common.inc.1.840 Tue Dec 30 17:27:43 2008 +++ includes/common.inc Tue Dec 30 17:49:01 2008 @@ -1921,6 +1921,27 @@ function drupal_eval($code) { } /** + * Attempt to increase the PHP maximum execution time. + * + * A wrapper around PHP's set_time_limit(). Checks the current time limit to + * make sure we don't accidentally reduce it, and avoids trying to change it + * in unfriendly server environments. + * + * @param $desired_time_limit + * (int) The desired time limit, in seconds. 0 means unlimited. + */ + +function drupal_set_time_limit($desired_time_limit) { + // Check if we can change the time limit. + $safe_mode = trim(ini_get('safe_mode')); + if ((empty($safe_mode) || strtolower($safe_mode) == 'off') && function_exists('set_time_limit') && strpos(ini_get('suhosin.executor.func.blacklist'), 'set_time_limit') === FALSE) { + if (($desired_time_limit == 0) || (is_numeric($current_time_limit = ini_get('max_execution_time')) && $current_time_limit > 0 && $desired_time_limit > $current_time_limit)) { + set_time_limit($desired_time_limit); + } + } +} + +/** * Returns the path to a system item (module, theme, etc.). * * @param $type @@ -3005,8 +3026,8 @@ function drupal_cron_run() { // Allow execution to continue even if the request gets canceled. @ignore_user_abort(TRUE); - // Increase the maximum execution time. - @set_time_limit(240); + // Try to increase the maximum execution time. + drupal_set_time_limit(240); // Fetch the cron semaphore $semaphore = variable_get('cron_semaphore', FALSE); Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.198 diff -u -p -r1.198 locale.inc --- includes/locale.inc 19 Dec 2008 03:55:23 -0000 1.198 +++ includes/locale.inc 25 Dec 2008 02:22:05 -0000 @@ -1025,10 +1025,8 @@ function locale_add_language($langcode, * Text group to import PO file into (eg. 'default' for interface translations) */ function _locale_import_po($file, $langcode, $mode, $group = NULL) { - // If not in 'safe mode', increase the maximum execution time. - if (!ini_get('safe_mode')) { - set_time_limit(240); - } + // Try to increase the maximum execution time. + drupal_set_time_limit(240); // Check if we have the language already in the database. if (!db_fetch_object(db_query("SELECT language FROM {languages} WHERE language = '%s'", $langcode))) { Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1004 diff -u -p -r1.1004 node.module --- modules/node/node.module 20 Dec 2008 18:24:38 -0000 1.1004 +++ modules/node/node.module 25 Dec 2008 02:22:06 -0000 @@ -2507,10 +2507,9 @@ function node_access_rebuild($batch_mode batch_set($batch); } else { - // If not in 'safe mode', increase the maximum execution time. - if (!ini_get('safe_mode')) { - set_time_limit(240); - } + // Try to increase the maximum execution time. + drupal_set_time_limit(240); + $result = db_query("SELECT nid FROM {node}"); while ($node = db_fetch_object($result)) { $loaded_node = node_load($node->nid, NULL, TRUE); --- modules/simpletest/tests/common.test.1.19 Tue Dec 30 17:27:45 2008 +++ modules/simpletest/tests/common.test Tue Dec 30 17:51:26 2008 @@ -592,4 +592,43 @@ class DrupalErrorCollectionUnitTest exte $this->assertEqual($error['message'], $message, t("Message was %message", array('%message' => $message))); } } -} \ No newline at end of file +} + +/** + * Test increasing PHP's maximum execution time. + * + * Note that these tests will fail if the server environment is not appropriate, + * i.e. if safe_mode is on, or if PHP's set_time_limit() is disabled. + * + * Also note that drupal_set_time_limit() doesn't do any checking on the validity + * of the supplied $desired_time_limit, so we don't test that here. + */ +class CommonTimeLimitTestCase extends DrupalWebTestCase { + function getInfo() { + return array( + 'name' => t('Set PHP maximum execution time'), + 'description' => t("Test increasing the PHP time limit. Requires safe_mode off, and PHP's set_time_limit() not disabled."), + 'group' => t('System'), + ); + } + + function testSetTimeLimit() { + // Check time limit not modified if existing value is invalid. + set_time_limit('invalid'); + drupal_set_time_limit(30); + $this->assertEqual(ini_get('max_execution_time'), 'invalid', t('Check time limit not modified if existing value is invalid.')); + + // Check we can't reduce the time limit. + set_time_limit(100); + drupal_set_time_limit(99); + $this->assertEqual(ini_get('max_execution_time'), 100, t("Check time limit can't be reduced.")); + + // Check we can increase the time limit. + drupal_set_time_limit(101); + $this->assertEqual(ini_get('max_execution_time'), 101, t('Check time limit can be increased.')); + + // Check we can set the time limit to 0 (unlimited). + drupal_set_time_limit(0); + $this->assertEqual(ini_get('max_execution_time'), 0, t('Check time limit can be set to unlimited.')); + } +} Index: scripts/run-tests.sh =================================================================== RCS file: /cvs/drupal/drupal/scripts/run-tests.sh,v retrieving revision 1.20 diff -u -p -r1.20 run-tests.sh --- scripts/run-tests.sh 20 Dec 2008 18:24:41 -0000 1.20 +++ scripts/run-tests.sh 25 Dec 2008 02:22:07 -0000 @@ -64,10 +64,8 @@ if ($args['list']) { $test_list = simpletest_script_get_test_list(); -// If not in 'safe mode', increase the maximum execution time. -if (!ini_get('safe_mode')) { - set_time_limit(0); -} +// Try to set unlimited execution time. +drupal_set_time_limit(0); simpletest_script_reporter_init();