}
/* }}} */
-ZEND_API void zend_timeout(int dummy) /* {{{ */
+static void zend_set_timeout_ex(zend_long seconds, int reset_signals);
+
+ZEND_API ZEND_NORETURN void zend_timeout(int dummy) /* {{{ */
{
- quiet_write(2, log_buffer, MIN(output_len, sizeof(log_buffer)));
+#if defined(PHP_WIN32)
+# ifndef ZTS
+ /* No action is needed if we're timed out because zero seconds are
+ just ignored. Also, the hard timeout needs to be respected. If the
+ timer is not restarted properly, it could hang in the shutdown
+ function. */
+ if (EG(hard_timeout) > 0) {
+ EG(timed_out) = 0;
+ zend_set_timeout_ex(EG(hard_timeout), 1);
+ /* XXX Abused, introduce an additional flag if the value needs to be kept. */
+ EG(hard_timeout) = 0;
+ }
+# endif
+#else
+ EG(timed_out) = 0;
+ zend_set_timeout_ex(0, 1);
+#endif
+
+ zend_error_noreturn(E_ERROR, "Maximum execution time of " ZEND_LONG_FMT " second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
+}
+/* }}} */
+
+#ifndef ZEND_WIN32
+static void zend_timeout_handler(int dummy) /* {{{ */
+{
+#ifndef ZTS
+ if (EG(timed_out)) {
+ /* Die on hard timeout */
+ const char *error_filename = NULL;
+ uint error_lineno = 0;
+ char log_buffer[2048];
+ int output_len = 0;
+
+ if (zend_is_compiling()) {
+ error_filename = ZSTR_VAL(zend_get_compiled_filename());
+ error_lineno = zend_get_compiled_lineno();
+ } else if (zend_is_executing()) {
+ error_filename = zend_get_executed_filename();
+ if (error_filename[0] == '[') { /* [no active file] */
+ error_filename = NULL;
+ error_lineno = 0;
+ } else {
+ error_lineno = zend_get_executed_lineno();
+ }
+ }
+ if (!error_filename) {
+ error_filename = "Unknown";
+ }
+
+ output_len = snprintf(log_buffer, sizeof(log_buffer), "\nFatal error: Maximum execution time of " ZEND_LONG_FMT "+" ZEND_LONG_FMT " seconds exceeded (terminated) in %s on line %d\n", EG(timeout_seconds), EG(hard_timeout), error_filename, error_lineno);
+ if (output_len > 0) {
++ write(2, log_buffer, MIN(output_len, sizeof(log_buffer)));
+ }
+ _exit(1);
+ }
+#endif
if (zend_on_timeout) {
#ifdef ZEND_SIGNALS