php-src/ext/opcache/zend_accelerator_module.c

859 lines
34 KiB
C
Raw Normal View History

2013-02-13 12:26:47 +00:00
/*
+----------------------------------------------------------------------+
| Zend OPcache |
2013-02-13 12:26:47 +00:00
+----------------------------------------------------------------------+
2018-01-02 04:55:14 +00:00
| Copyright (c) 1998-2018 The PHP Group |
2013-02-13 12:26:47 +00:00
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
| Stanislav Malyshev <stas@zend.com> |
| Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#include <time.h>
#include "php.h"
#include "ZendAccelerator.h"
#include "zend_API.h"
#include "zend_shared_alloc.h"
#include "zend_accelerator_blacklist.h"
#include "php_ini.h"
#include "SAPI.h"
2014-08-15 08:40:07 +00:00
#include "zend_virtual_cwd.h"
2013-02-13 12:26:47 +00:00
#include "ext/standard/info.h"
#include "ext/standard/php_filestat.h"
#define STRING_NOT_NULL(s) (NULL == (s)?"":s)
#define MIN_ACCEL_FILES 200
#define MAX_ACCEL_FILES 1000000
2013-02-13 12:26:47 +00:00
#define TOKENTOSTR(X) #X
static zif_handler orig_file_exists = NULL;
static zif_handler orig_is_file = NULL;
static zif_handler orig_is_readable = NULL;
2013-03-16 12:08:11 +00:00
2013-04-10 12:45:59 +00:00
ZEND_BEGIN_ARG_INFO(arginfo_opcache_none, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_get_status, 0, 0, 0)
ZEND_ARG_INFO(0, fetch_scripts)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_compile_file, 0, 0, 1)
ZEND_ARG_INFO(0, file)
ZEND_END_ARG_INFO()
2013-04-10 12:45:59 +00:00
ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_invalidate, 0, 0, 1)
ZEND_ARG_INFO(0, script)
ZEND_ARG_INFO(0, force)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_is_script_cached, 0, 0, 1)
ZEND_ARG_INFO(0, script)
ZEND_END_ARG_INFO()
2013-02-13 12:26:47 +00:00
/* User functions */
static ZEND_FUNCTION(opcache_reset);
static ZEND_FUNCTION(opcache_invalidate);
static ZEND_FUNCTION(opcache_is_script_cached);
2013-02-13 12:26:47 +00:00
/* Private functions */
static ZEND_FUNCTION(opcache_get_status);
static ZEND_FUNCTION(opcache_compile_file);
static ZEND_FUNCTION(opcache_get_configuration);
2013-02-13 12:26:47 +00:00
static zend_function_entry accel_functions[] = {
/* User functions */
2013-04-10 12:45:59 +00:00
ZEND_FE(opcache_reset, arginfo_opcache_none)
ZEND_FE(opcache_invalidate, arginfo_opcache_invalidate)
ZEND_FE(opcache_compile_file, arginfo_opcache_compile_file)
ZEND_FE(opcache_is_script_cached, arginfo_opcache_is_script_cached)
2013-02-13 12:26:47 +00:00
/* Private functions */
2013-04-10 12:45:59 +00:00
ZEND_FE(opcache_get_configuration, arginfo_opcache_none)
ZEND_FE(opcache_get_status, arginfo_opcache_get_status)
2016-06-21 17:12:29 +00:00
ZEND_FE_END
2013-02-13 12:26:47 +00:00
};
2014-12-13 22:06:14 +00:00
static int validate_api_restriction(void)
{
if (ZCG(accel_directives).restrict_api && *ZCG(accel_directives).restrict_api) {
2016-06-21 17:12:29 +00:00
size_t len = strlen(ZCG(accel_directives).restrict_api);
if (!SG(request_info).path_translated ||
strlen(SG(request_info).path_translated) < len ||
memcmp(SG(request_info).path_translated, ZCG(accel_directives).restrict_api, len) != 0) {
zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " API is restricted by \"restrict_api\" configuration directive");
return 0;
}
2015-01-03 09:22:58 +00:00
}
return 1;
}
2013-02-13 12:26:47 +00:00
static ZEND_INI_MH(OnUpdateMemoryConsumption)
{
2014-08-25 17:24:55 +00:00
zend_long *p;
zend_long memsize;
2013-02-13 12:26:47 +00:00
#ifndef ZTS
char *base = (char *) mh_arg2;
#else
char *base = (char *) ts_resource(*((int *) mh_arg2));
#endif
/* keep the compiler happy */
(void)entry; (void)mh_arg2; (void)mh_arg3; (void)stage;
2013-02-13 12:26:47 +00:00
2014-08-25 17:24:55 +00:00
p = (zend_long *) (base + (size_t)mh_arg1);
memsize = atoi(ZSTR_VAL(new_value));
2013-02-13 12:26:47 +00:00
/* sanity check we must use at least 8 MB */
if (memsize < 8) {
const char *new_new_value = "8";
zend_ini_entry *ini_entry;
memsize = 8;
zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption is set below the required 8MB.\n");
2013-03-11 18:49:05 +00:00
zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the minimal 8MB configuration.\n");
2013-02-13 12:26:47 +00:00
2014-03-28 19:34:49 +00:00
if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives),
"opcache.memory_consumption",
2014-03-28 19:34:49 +00:00
sizeof("opcache.memory_consumption")-1)) == NULL) {
2013-02-13 12:26:47 +00:00
return FAILURE;
}
ini_entry->value = zend_string_init(new_new_value, 1, 1);
2013-02-13 12:26:47 +00:00
}
2016-12-01 07:30:02 +00:00
if (UNEXPECTED(memsize > ZEND_ULONG_MAX / (1024 * 1024))) {
2016-11-17 10:17:34 +00:00
*p = ZEND_ULONG_MAX;
2016-12-01 07:30:02 +00:00
} else {
*p = memsize * (1024 * 1024);
2016-11-17 10:17:34 +00:00
}
2013-02-13 12:26:47 +00:00
return SUCCESS;
}
static ZEND_INI_MH(OnUpdateMaxAcceleratedFiles)
{
2014-08-25 17:24:55 +00:00
zend_long *p;
zend_long size;
2013-02-13 12:26:47 +00:00
#ifndef ZTS
char *base = (char *) mh_arg2;
#else
char *base = (char *) ts_resource(*((int *) mh_arg2));
#endif
/* keep the compiler happy */
(void)entry; (void)mh_arg2; (void)mh_arg3; (void)stage;
2013-02-13 12:26:47 +00:00
2014-08-25 17:24:55 +00:00
p = (zend_long *) (base + (size_t)mh_arg1);
size = atoi(ZSTR_VAL(new_value));
2013-02-13 12:26:47 +00:00
/* sanity check we must use a value between MIN_ACCEL_FILES and MAX_ACCEL_FILES */
if (size < MIN_ACCEL_FILES || size > MAX_ACCEL_FILES) {
const char *new_new_value;
zend_ini_entry *ini_entry;
2013-02-22 06:56:05 +00:00
if (size < MIN_ACCEL_FILES) {
2013-02-13 12:26:47 +00:00
size = MIN_ACCEL_FILES;
new_new_value = TOKENTOSTR(MIN_ACCEL_FILES);
zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set below the required minimum (%d).\n", MIN_ACCEL_FILES);
2013-03-11 18:49:05 +00:00
zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the minimal configuration.\n");
2013-02-13 12:26:47 +00:00
}
2013-02-22 06:56:05 +00:00
if (size > MAX_ACCEL_FILES) {
2013-02-13 12:26:47 +00:00
size = MAX_ACCEL_FILES;
new_new_value = TOKENTOSTR(MAX_ACCEL_FILES);
zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set above the limit (%d).\n", MAX_ACCEL_FILES);
2013-03-11 18:49:05 +00:00
zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the maximal configuration.\n");
2013-02-13 12:26:47 +00:00
}
2014-03-28 19:34:49 +00:00
if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives),
"opcache.max_accelerated_files",
2014-03-28 19:34:49 +00:00
sizeof("opcache.max_accelerated_files")-1)) == NULL) {
2013-02-13 12:26:47 +00:00
return FAILURE;
}
ini_entry->value = zend_string_init(new_new_value, strlen(new_new_value), 1);
2013-02-13 12:26:47 +00:00
}
*p = size;
return SUCCESS;
}
static ZEND_INI_MH(OnUpdateMaxWastedPercentage)
{
double *p;
2014-08-25 17:24:55 +00:00
zend_long percentage;
2013-02-13 12:26:47 +00:00
#ifndef ZTS
char *base = (char *) mh_arg2;
#else
char *base = (char *) ts_resource(*((int *) mh_arg2));
#endif
/* keep the compiler happy */
(void)entry; (void)mh_arg2; (void)mh_arg3; (void)stage;
2013-02-13 12:26:47 +00:00
2013-02-25 07:29:54 +00:00
p = (double *) (base + (size_t)mh_arg1);
percentage = atoi(ZSTR_VAL(new_value));
2013-02-13 12:26:47 +00:00
if (percentage <= 0 || percentage > 50) {
const char *new_new_value = "5";
zend_ini_entry *ini_entry;
percentage = 5;
zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_wasted_percentage must be set between 1 and 50.\n");
zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use 5%%.\n");
2014-03-28 19:34:49 +00:00
if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives),
"opcache.max_wasted_percentage",
2014-03-28 19:34:49 +00:00
sizeof("opcache.max_wasted_percentage")-1)) == NULL) {
2013-02-13 12:26:47 +00:00
return FAILURE;
}
ini_entry->value = zend_string_init(new_new_value, strlen(new_new_value), 1);
2013-02-13 12:26:47 +00:00
}
*p = (double)percentage / 100.0;
return SUCCESS;
}
static ZEND_INI_MH(OnEnable)
{
if (stage == ZEND_INI_STAGE_STARTUP ||
stage == ZEND_INI_STAGE_SHUTDOWN ||
stage == ZEND_INI_STAGE_DEACTIVATE) {
2014-12-13 22:06:14 +00:00
return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
} else {
/* It may be only temporary disabled */
zend_bool *p;
#ifndef ZTS
char *base = (char *) mh_arg2;
#else
char *base = (char *) ts_resource(*((int *) mh_arg2));
#endif
p = (zend_bool *) (base+(size_t) mh_arg1);
if ((ZSTR_LEN(new_value) == 2 && strcasecmp("on", ZSTR_VAL(new_value)) == 0) ||
(ZSTR_LEN(new_value) == 3 && strcasecmp("yes", ZSTR_VAL(new_value)) == 0) ||
(ZSTR_LEN(new_value) == 4 && strcasecmp("true", ZSTR_VAL(new_value)) == 0) ||
atoi(ZSTR_VAL(new_value)) != 0) {
zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporary enabled (it may be only disabled till the end of request)");
return FAILURE;
} else {
*p = 0;
return SUCCESS;
}
}
}
#ifdef HAVE_OPCACHE_FILE_CACHE
static ZEND_INI_MH(OnUpdateFileCache)
{
if (new_value) {
if (!ZSTR_LEN(new_value)) {
new_value = NULL;
} else {
zend_stat_t buf;
if (!IS_ABSOLUTE_PATH(ZSTR_VAL(new_value), ZSTR_LEN(new_value)) ||
zend_stat(ZSTR_VAL(new_value), &buf) != 0 ||
!S_ISDIR(buf.st_mode) ||
#ifndef ZEND_WIN32
access(ZSTR_VAL(new_value), R_OK | W_OK | X_OK) != 0) {
#else
_access(ZSTR_VAL(new_value), 06) != 0) {
#endif
zend_accel_error(ACCEL_LOG_WARNING, "opcache.file_cache must be a full path of accessable directory.\n");
new_value = NULL;
}
}
}
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
return SUCCESS;
}
#endif
2013-02-13 12:26:47 +00:00
ZEND_INI_BEGIN()
STD_PHP_INI_BOOLEAN("opcache.enable" , "1", PHP_INI_ALL, OnEnable, enabled , zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.use_cwd" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.use_cwd , zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.validate_timestamps", "1", PHP_INI_ALL , OnUpdateBool, accel_directives.validate_timestamps, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.validate_permission", "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_permission, zend_accel_globals, accel_globals)
#ifndef ZEND_WIN32
STD_PHP_INI_BOOLEAN("opcache.validate_root" , "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_root , zend_accel_globals, accel_globals)
#endif
STD_PHP_INI_BOOLEAN("opcache.inherited_hack" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.inherited_hack , zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.dups_fix" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.ignore_dups , zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.revalidate_path" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.revalidate_path , zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.log_verbosity_level" , "1" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.log_verbosity_level, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.memory_consumption" , "128" , PHP_INI_SYSTEM, OnUpdateMemoryConsumption, accel_directives.memory_consumption, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.interned_strings_buffer", "8" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.interned_strings_buffer, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.max_accelerated_files" , "10000", PHP_INI_SYSTEM, OnUpdateMaxAcceleratedFiles, accel_directives.max_accelerated_files, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.max_wasted_percentage" , "5" , PHP_INI_SYSTEM, OnUpdateMaxWastedPercentage, accel_directives.max_wasted_percentage, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.consistency_checks" , "0" , PHP_INI_ALL , OnUpdateLong, accel_directives.consistency_checks, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.force_restart_timeout" , "180" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.force_restart_timeout, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.revalidate_freq" , "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.revalidate_freq, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.file_update_protection", "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.file_update_protection, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.blacklist_filename" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.user_blacklist_filename, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.max_file_size" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.max_file_size, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.protect_memory" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.protect_memory, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.save_comments" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.save_comments, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.optimization_level" , DEFAULT_OPTIMIZATION_LEVEL , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.optimization_level, zend_accel_globals, accel_globals)
2015-12-09 11:52:00 +00:00
STD_PHP_INI_ENTRY("opcache.opt_debug_level" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.opt_debug_level, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals)
2013-02-13 12:26:47 +00:00
2016-04-12 07:30:11 +00:00
#ifndef ZEND_WIN32
STD_PHP_INI_ENTRY("opcache.lockfile_path" , "/tmp" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.lockfile_path, zend_accel_globals, accel_globals)
#else
STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals)
2013-02-13 12:26:47 +00:00
#endif
#ifdef HAVE_OPCACHE_FILE_CACHE
STD_PHP_INI_ENTRY("opcache.file_cache" , NULL , PHP_INI_SYSTEM, OnUpdateFileCache, accel_directives.file_cache, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.file_cache_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_only, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.file_cache_consistency_checks" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_consistency_checks, zend_accel_globals, accel_globals)
#endif
#if ENABLE_FILE_CACHE_FALLBACK
STD_PHP_INI_ENTRY("opcache.file_cache_fallback" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_fallback, zend_accel_globals, accel_globals)
#endif
#ifdef HAVE_HUGE_CODE_PAGES
STD_PHP_INI_BOOLEAN("opcache.huge_code_pages" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.huge_code_pages, zend_accel_globals, accel_globals)
#endif
2013-02-13 12:26:47 +00:00
ZEND_INI_END()
static int filename_is_in_cache(zend_string *filename)
2013-02-13 12:26:47 +00:00
{
char *key;
int key_length;
key = accel_make_persistent_key(ZSTR_VAL(filename), ZSTR_LEN(filename), &key_length);
2015-03-05 23:13:47 +00:00
if (key != NULL) {
2015-03-06 13:26:40 +00:00
zend_persistent_script *persistent_script = zend_accel_hash_str_find(&ZCSG(hash), key, key_length);
2015-03-05 23:13:47 +00:00
if (persistent_script && !persistent_script->corrupted) {
zend_file_handle handle = {{0}, NULL, NULL, 0, 0};
2013-02-13 12:26:47 +00:00
handle.filename = ZSTR_VAL(filename);
2015-03-05 23:13:47 +00:00
handle.type = ZEND_HANDLE_FILENAME;
2013-02-13 12:26:47 +00:00
if (ZCG(accel_directives).validate_timestamps) {
return validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS;
}
return 1;
2015-03-05 23:13:47 +00:00
}
2013-02-13 12:26:47 +00:00
}
return 0;
}
2013-03-16 12:08:11 +00:00
static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS)
2013-02-13 12:26:47 +00:00
{
2014-03-28 19:34:49 +00:00
zval zfilename;
2013-02-13 12:26:47 +00:00
2013-03-16 12:08:11 +00:00
if (ZEND_NUM_ARGS() != 1 ||
zend_get_parameters_array_ex(1, &zfilename) == FAILURE ||
2014-03-28 19:34:49 +00:00
Z_TYPE(zfilename) != IS_STRING ||
2014-08-25 17:24:55 +00:00
Z_STRLEN(zfilename) == 0) {
2013-03-16 12:08:11 +00:00
return 0;
2013-02-13 12:26:47 +00:00
}
return filename_is_in_cache(Z_STR(zfilename));
2013-02-13 12:26:47 +00:00
}
static ZEND_NAMED_FUNCTION(accel_file_exists)
2013-02-13 12:26:47 +00:00
{
2013-03-16 12:08:11 +00:00
if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
RETURN_TRUE;
} else {
orig_file_exists(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
2013-02-13 12:26:47 +00:00
}
static ZEND_NAMED_FUNCTION(accel_is_file)
2013-02-13 12:26:47 +00:00
{
2013-03-16 12:08:11 +00:00
if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
RETURN_TRUE;
} else {
orig_is_file(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
2013-02-13 12:26:47 +00:00
}
static ZEND_NAMED_FUNCTION(accel_is_readable)
2013-02-13 12:26:47 +00:00
{
2013-03-16 12:08:11 +00:00
if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
RETURN_TRUE;
} else {
orig_is_readable(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
2013-02-13 12:26:47 +00:00
}
static ZEND_MINIT_FUNCTION(zend_accelerator)
{
(void)type; /* keep the compiler happy */
REGISTER_INI_ENTRIES();
2014-08-15 08:40:07 +00:00
2013-02-13 12:26:47 +00:00
return SUCCESS;
}
2014-12-13 22:06:14 +00:00
void zend_accel_override_file_functions(void)
2013-02-13 12:26:47 +00:00
{
zend_function *old_function;
if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).file_override_enabled) {
2015-05-07 05:46:56 +00:00
#ifdef HAVE_OPCACHE_FILE_CACHE
if (file_cache_only) {
2015-05-07 03:25:04 +00:00
zend_accel_error(ACCEL_LOG_WARNING, "file_override_enabled has no effect when file_cache_only is set");
return;
}
2015-05-07 05:46:56 +00:00
#endif
2013-02-13 12:26:47 +00:00
/* override file_exists */
2014-03-28 19:34:49 +00:00
if ((old_function = zend_hash_str_find_ptr(CG(function_table), "file_exists", sizeof("file_exists")-1)) != NULL) {
2013-03-16 12:08:11 +00:00
orig_file_exists = old_function->internal_function.handler;
2013-02-13 12:26:47 +00:00
old_function->internal_function.handler = accel_file_exists;
}
2014-03-28 19:34:49 +00:00
if ((old_function = zend_hash_str_find_ptr(CG(function_table), "is_file", sizeof("is_file")-1)) != NULL) {
2013-03-16 12:08:11 +00:00
orig_is_file = old_function->internal_function.handler;
2013-02-13 12:26:47 +00:00
old_function->internal_function.handler = accel_is_file;
}
2014-03-28 19:34:49 +00:00
if ((old_function = zend_hash_str_find_ptr(CG(function_table), "is_readable", sizeof("is_readable")-1)) != NULL) {
2013-03-16 12:08:11 +00:00
orig_is_readable = old_function->internal_function.handler;
2013-02-13 12:26:47 +00:00
old_function->internal_function.handler = accel_is_readable;
}
}
}
static ZEND_MSHUTDOWN_FUNCTION(zend_accelerator)
{
(void)type; /* keep the compiler happy */
UNREGISTER_INI_ENTRIES();
2014-12-13 22:06:14 +00:00
accel_shutdown();
2013-02-13 12:26:47 +00:00
return SUCCESS;
}
void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS)
{
php_info_print_table_start();
if (
#ifdef HAVE_OPCACHE_FILE_CACHE
(ZCG(accelerator_enabled) || file_cache_only)
#else
(ZCG(accelerator_enabled))
#endif
) {
2013-02-13 12:26:47 +00:00
php_info_print_table_row(2, "Opcode Caching", "Up and Running");
} else {
php_info_print_table_row(2, "Opcode Caching", "Disabled");
}
if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).optimization_level) {
2013-02-13 12:26:47 +00:00
php_info_print_table_row(2, "Optimization", "Enabled");
} else {
php_info_print_table_row(2, "Optimization", "Disabled");
}
#ifdef HAVE_OPCACHE_FILE_CACHE
if (!file_cache_only) {
php_info_print_table_row(2, "SHM Cache", "Enabled");
} else {
php_info_print_table_row(2, "SHM Cache", "Disabled");
}
if (ZCG(accel_directives).file_cache) {
php_info_print_table_row(2, "File Cache", "Enabled");
} else {
php_info_print_table_row(2, "File Cache", "Disabled");
}
if (file_cache_only) {
if (!accel_startup_ok || zps_api_failure_reason) {
php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason);
} else {
php_info_print_table_row(2, "Startup", "OK");
}
} else
#endif
if (ZCG(enabled)) {
if (!accel_startup_ok || zps_api_failure_reason) {
php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason);
} else {
2013-03-19 06:17:44 +00:00
char buf[32];
php_info_print_table_row(2, "Startup", "OK");
php_info_print_table_row(2, "Shared memory model", zend_accel_get_shared_model());
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, (zend_ulong)ZCSG(hits));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Cache hits", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Cache misses", buf);
2014-08-25 18:22:49 +00:00
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Used memory", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, zend_shared_alloc_get_free_memory());
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Free memory", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZSMMG(wasted_shared_memory));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Wasted memory", buf);
if (ZCSG(interned_strings_start) && ZCSG(interned_strings_end) && ZCSG(interned_strings_top)) {
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCSG(interned_strings_top) - ZCSG(interned_strings_start));
php_info_print_table_row(2, "Interned Strings Used memory", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCSG(interned_strings_end) - ZCSG(interned_strings_top));
php_info_print_table_row(2, "Interned Strings Free memory", buf);
}
snprintf(buf, sizeof(buf), "%d", ZCSG(hash).num_direct_entries);
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Cached scripts", buf);
snprintf(buf, sizeof(buf), "%d", ZCSG(hash).num_entries);
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Cached keys", buf);
snprintf(buf, sizeof(buf), "%d", ZCSG(hash).max_num_entries);
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Max keys", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCSG(oom_restarts));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "OOM restarts", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCSG(hash_restarts));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Hash keys restarts", buf);
snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCSG(manual_restarts));
2013-03-19 06:17:44 +00:00
php_info_print_table_row(2, "Manual restarts", buf);
}
2013-02-13 12:26:47 +00:00
}
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
static zend_module_entry accel_module_entry = {
STANDARD_MODULE_HEADER,
ACCELERATOR_PRODUCT_NAME,
accel_functions,
ZEND_MINIT(zend_accelerator),
ZEND_MSHUTDOWN(zend_accelerator),
NULL,
NULL,
zend_accel_info,
2016-05-17 14:16:10 +00:00
PHP_VERSION,
NO_MODULE_GLOBALS,
accel_post_deactivate,
STANDARD_MODULE_PROPERTIES_EX
2013-02-13 12:26:47 +00:00
};
2014-12-13 22:06:14 +00:00
int start_accel_module(void)
{
2014-12-13 22:06:14 +00:00
return zend_startup_module(&accel_module_entry);
}
2013-02-13 12:26:47 +00:00
/* {{{ proto array accelerator_get_scripts()
Get the scripts which are accelerated by ZendAccelerator */
2014-12-13 22:06:14 +00:00
static int accelerator_get_scripts(zval *return_value)
2013-02-13 12:26:47 +00:00
{
uint32_t i;
2014-03-28 19:34:49 +00:00
zval persistent_script_report;
2013-02-13 12:26:47 +00:00
zend_accel_hash_entry *cache_entry;
struct tm *ta;
struct timeval exec_time;
struct timeval fetch_time;
if (!ZCG(accelerator_enabled) || accelerator_shm_read_lock() != SUCCESS) {
2013-02-13 12:26:47 +00:00
return 0;
}
array_init(return_value);
2013-02-22 06:56:05 +00:00
for (i = 0; i<ZCSG(hash).max_num_entries; i++) {
for (cache_entry = ZCSG(hash).hash_table[i]; cache_entry; cache_entry = cache_entry->next) {
2013-02-13 12:26:47 +00:00
zend_persistent_script *script;
2013-03-18 09:36:31 +00:00
char *str;
2013-03-19 06:45:38 +00:00
size_t len;
2013-02-13 12:26:47 +00:00
if (cache_entry->indirect) continue;
script = (zend_persistent_script *)cache_entry->data;
2014-03-28 19:34:49 +00:00
array_init(&persistent_script_report);
add_assoc_str(&persistent_script_report, "full_path", zend_string_dup(script->script.filename, 0));
2014-08-25 17:24:55 +00:00
add_assoc_long(&persistent_script_report, "hits", (zend_long)script->dynamic_members.hits);
add_assoc_long(&persistent_script_report, "memory_consumption", script->dynamic_members.memory_consumption);
2013-02-13 12:26:47 +00:00
ta = localtime(&script->dynamic_members.last_used);
2013-03-18 09:36:31 +00:00
str = asctime(ta);
len = strlen(str);
if (len > 0 && str[len - 1] == '\n') len--;
2014-04-15 11:40:40 +00:00
add_assoc_stringl(&persistent_script_report, "last_used", str, len);
2014-08-25 17:24:55 +00:00
add_assoc_long(&persistent_script_report, "last_used_timestamp", script->dynamic_members.last_used);
2013-02-13 12:26:47 +00:00
if (ZCG(accel_directives).validate_timestamps) {
2014-08-25 17:24:55 +00:00
add_assoc_long(&persistent_script_report, "timestamp", (zend_long)script->timestamp);
2013-02-13 12:26:47 +00:00
}
timerclear(&exec_time);
timerclear(&fetch_time);
2014-10-26 23:59:17 +00:00
zend_hash_str_update(Z_ARRVAL_P(return_value), cache_entry->key, cache_entry->key_length, &persistent_script_report);
2013-02-13 12:26:47 +00:00
}
}
2014-12-13 22:06:14 +00:00
accelerator_shm_read_unlock();
2013-02-13 12:26:47 +00:00
2014-03-28 19:34:49 +00:00
return 1;
2013-02-13 12:26:47 +00:00
}
/* {{{ proto array accelerator_get_status([bool fetch_scripts])
Obtain statistics information regarding code acceleration */
static ZEND_FUNCTION(opcache_get_status)
2013-02-13 12:26:47 +00:00
{
2014-08-25 17:24:55 +00:00
zend_long reqs;
2014-03-28 19:34:49 +00:00
zval memory_usage, statistics, scripts;
zend_bool fetch_scripts = 1;
2013-02-13 12:26:47 +00:00
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &fetch_scripts) == FAILURE) {
return;
}
2015-01-03 09:22:58 +00:00
2014-12-13 22:06:14 +00:00
if (!validate_api_restriction()) {
RETURN_FALSE;
}
if (!accel_startup_ok) {
2013-02-13 12:26:47 +00:00
RETURN_FALSE;
}
array_init(return_value);
/* Trivia */
add_assoc_bool(return_value, "opcache_enabled", ZCG(accelerator_enabled));
#ifdef HAVE_OPCACHE_FILE_CACHE
if (ZCG(accel_directives).file_cache) {
add_assoc_string(return_value, "file_cache", ZCG(accel_directives).file_cache);
}
if (file_cache_only) {
add_assoc_bool(return_value, "file_cache_only", 1);
return;
}
#endif
2013-02-13 12:26:47 +00:00
add_assoc_bool(return_value, "cache_full", ZSMMG(memory_exhausted));
add_assoc_bool(return_value, "restart_pending", ZCSG(restart_pending));
add_assoc_bool(return_value, "restart_in_progress", ZCSG(restart_in_progress));
2013-02-13 12:26:47 +00:00
/* Memory usage statistics */
2014-03-28 19:34:49 +00:00
array_init(&memory_usage);
2014-08-25 17:24:55 +00:00
add_assoc_long(&memory_usage, "used_memory", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory));
add_assoc_long(&memory_usage, "free_memory", zend_shared_alloc_get_free_memory());
add_assoc_long(&memory_usage, "wasted_memory", ZSMMG(wasted_shared_memory));
2014-03-28 19:34:49 +00:00
add_assoc_double(&memory_usage, "current_wasted_percentage", (((double) ZSMMG(wasted_shared_memory))/ZCG(accel_directives).memory_consumption)*100.0);
add_assoc_zval(return_value, "memory_usage", &memory_usage);
2013-02-13 12:26:47 +00:00
if (ZCSG(interned_strings_start) && ZCSG(interned_strings_end) && ZCSG(interned_strings_top)) {
Merge mainstream 'master' branch into refactoring During merge I had to revert: Nikita's patch for php_splice() (it probably needs to be applyed again) Bob Weinand's patches related to constant expression handling (we need to review them carefully) I also reverted all our attempts to support sapi/phpdbg (we didn't test it anyway) Conflicts: Zend/zend.h Zend/zend_API.c Zend/zend_ast.c Zend/zend_compile.c Zend/zend_compile.h Zend/zend_constants.c Zend/zend_exceptions.c Zend/zend_execute.c Zend/zend_execute.h Zend/zend_execute_API.c Zend/zend_hash.c Zend/zend_highlight.c Zend/zend_language_parser.y Zend/zend_language_scanner.c Zend/zend_language_scanner_defs.h Zend/zend_variables.c Zend/zend_vm_def.h Zend/zend_vm_execute.h ext/date/php_date.c ext/dom/documenttype.c ext/hash/hash.c ext/iconv/iconv.c ext/mbstring/tests/zend_multibyte-10.phpt ext/mbstring/tests/zend_multibyte-11.phpt ext/mbstring/tests/zend_multibyte-12.phpt ext/mysql/php_mysql.c ext/mysqli/mysqli.c ext/mysqlnd/mysqlnd_reverse_api.c ext/mysqlnd/php_mysqlnd.c ext/opcache/ZendAccelerator.c ext/opcache/zend_accelerator_util_funcs.c ext/opcache/zend_persist.c ext/opcache/zend_persist_calc.c ext/pcre/php_pcre.c ext/pdo/pdo_dbh.c ext/pdo/pdo_stmt.c ext/pdo_pgsql/pgsql_driver.c ext/pgsql/pgsql.c ext/reflection/php_reflection.c ext/session/session.c ext/spl/spl_array.c ext/spl/spl_observer.c ext/standard/array.c ext/standard/basic_functions.c ext/standard/html.c ext/standard/mail.c ext/standard/php_array.h ext/standard/proc_open.c ext/standard/streamsfuncs.c ext/standard/user_filters.c ext/standard/var_unserializer.c ext/standard/var_unserializer.re main/php_variables.c sapi/phpdbg/phpdbg.c sapi/phpdbg/phpdbg_bp.c sapi/phpdbg/phpdbg_frame.c sapi/phpdbg/phpdbg_help.c sapi/phpdbg/phpdbg_list.c sapi/phpdbg/phpdbg_print.c sapi/phpdbg/phpdbg_prompt.c
2014-04-25 20:32:51 +00:00
zval interned_strings_usage;
array_init(&interned_strings_usage);
2014-08-25 17:24:55 +00:00
add_assoc_long(&interned_strings_usage, "buffer_size", ZCSG(interned_strings_end) - ZCSG(interned_strings_start));
add_assoc_long(&interned_strings_usage, "used_memory", ZCSG(interned_strings_top) - ZCSG(interned_strings_start));
add_assoc_long(&interned_strings_usage, "free_memory", ZCSG(interned_strings_end) - ZCSG(interned_strings_top));
add_assoc_long(&interned_strings_usage, "number_of_strings", ZCSG(interned_strings).nNumOfElements);
Merge mainstream 'master' branch into refactoring During merge I had to revert: Nikita's patch for php_splice() (it probably needs to be applyed again) Bob Weinand's patches related to constant expression handling (we need to review them carefully) I also reverted all our attempts to support sapi/phpdbg (we didn't test it anyway) Conflicts: Zend/zend.h Zend/zend_API.c Zend/zend_ast.c Zend/zend_compile.c Zend/zend_compile.h Zend/zend_constants.c Zend/zend_exceptions.c Zend/zend_execute.c Zend/zend_execute.h Zend/zend_execute_API.c Zend/zend_hash.c Zend/zend_highlight.c Zend/zend_language_parser.y Zend/zend_language_scanner.c Zend/zend_language_scanner_defs.h Zend/zend_variables.c Zend/zend_vm_def.h Zend/zend_vm_execute.h ext/date/php_date.c ext/dom/documenttype.c ext/hash/hash.c ext/iconv/iconv.c ext/mbstring/tests/zend_multibyte-10.phpt ext/mbstring/tests/zend_multibyte-11.phpt ext/mbstring/tests/zend_multibyte-12.phpt ext/mysql/php_mysql.c ext/mysqli/mysqli.c ext/mysqlnd/mysqlnd_reverse_api.c ext/mysqlnd/php_mysqlnd.c ext/opcache/ZendAccelerator.c ext/opcache/zend_accelerator_util_funcs.c ext/opcache/zend_persist.c ext/opcache/zend_persist_calc.c ext/pcre/php_pcre.c ext/pdo/pdo_dbh.c ext/pdo/pdo_stmt.c ext/pdo_pgsql/pgsql_driver.c ext/pgsql/pgsql.c ext/reflection/php_reflection.c ext/session/session.c ext/spl/spl_array.c ext/spl/spl_observer.c ext/standard/array.c ext/standard/basic_functions.c ext/standard/html.c ext/standard/mail.c ext/standard/php_array.h ext/standard/proc_open.c ext/standard/streamsfuncs.c ext/standard/user_filters.c ext/standard/var_unserializer.c ext/standard/var_unserializer.re main/php_variables.c sapi/phpdbg/phpdbg.c sapi/phpdbg/phpdbg_bp.c sapi/phpdbg/phpdbg_frame.c sapi/phpdbg/phpdbg_help.c sapi/phpdbg/phpdbg_list.c sapi/phpdbg/phpdbg_print.c sapi/phpdbg/phpdbg_prompt.c
2014-04-25 20:32:51 +00:00
add_assoc_zval(return_value, "interned_strings_usage", &interned_strings_usage);
}
2015-01-03 09:22:58 +00:00
2013-02-13 12:26:47 +00:00
/* Accelerator statistics */
2014-03-28 19:34:49 +00:00
array_init(&statistics);
2014-08-25 17:24:55 +00:00
add_assoc_long(&statistics, "num_cached_scripts", ZCSG(hash).num_direct_entries);
add_assoc_long(&statistics, "num_cached_keys", ZCSG(hash).num_entries);
add_assoc_long(&statistics, "max_cached_keys", ZCSG(hash).max_num_entries);
add_assoc_long(&statistics, "hits", (zend_long)ZCSG(hits));
add_assoc_long(&statistics, "start_time", ZCSG(start_time));
add_assoc_long(&statistics, "last_restart_time", ZCSG(last_restart_time));
add_assoc_long(&statistics, "oom_restarts", ZCSG(oom_restarts));
add_assoc_long(&statistics, "hash_restarts", ZCSG(hash_restarts));
add_assoc_long(&statistics, "manual_restarts", ZCSG(manual_restarts));
add_assoc_long(&statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses));
add_assoc_long(&statistics, "blacklist_misses", ZCSG(blacklist_misses));
2013-02-13 12:26:47 +00:00
reqs = ZCSG(hits)+ZCSG(misses);
2014-03-28 19:34:49 +00:00
add_assoc_double(&statistics, "blacklist_miss_ratio", reqs?(((double) ZCSG(blacklist_misses))/reqs)*100.0:0);
add_assoc_double(&statistics, "opcache_hit_rate", reqs?(((double) ZCSG(hits))/reqs)*100.0:0);
add_assoc_zval(return_value, "opcache_statistics", &statistics);
2013-02-13 12:26:47 +00:00
if (fetch_scripts) {
/* accelerated scripts */
2014-12-13 22:06:14 +00:00
if (accelerator_get_scripts(&scripts)) {
2014-03-28 19:34:49 +00:00
add_assoc_zval(return_value, "scripts", &scripts);
}
2013-02-13 12:26:47 +00:00
}
}
2014-12-13 22:06:14 +00:00
static int add_blacklist_path(zend_blacklist_entry *p, zval *return_value)
2013-02-13 12:26:47 +00:00
{
2014-04-15 11:40:40 +00:00
add_next_index_stringl(return_value, p->path, p->path_length);
2013-02-13 12:26:47 +00:00
return 0;
}
/* {{{ proto array accelerator_get_configuration()
Obtain configuration information */
static ZEND_FUNCTION(opcache_get_configuration)
2013-02-13 12:26:47 +00:00
{
2014-03-28 19:34:49 +00:00
zval directives, version, blacklist;
2013-02-13 12:26:47 +00:00
if (zend_parse_parameters_none() == FAILURE) {
2013-02-27 18:54:56 +00:00
RETURN_FALSE;
}
2014-12-13 22:06:14 +00:00
if (!validate_api_restriction()) {
RETURN_FALSE;
}
2013-02-13 12:26:47 +00:00
array_init(return_value);
/* directives */
2014-03-28 19:34:49 +00:00
array_init(&directives);
add_assoc_bool(&directives, "opcache.enable", ZCG(enabled));
add_assoc_bool(&directives, "opcache.enable_cli", ZCG(accel_directives).enable_cli);
add_assoc_bool(&directives, "opcache.use_cwd", ZCG(accel_directives).use_cwd);
add_assoc_bool(&directives, "opcache.validate_timestamps", ZCG(accel_directives).validate_timestamps);
add_assoc_bool(&directives, "opcache.validate_permission", ZCG(accel_directives).validate_permission);
#ifndef ZEND_WIN32
add_assoc_bool(&directives, "opcache.validate_root", ZCG(accel_directives).validate_root);
#endif
2014-03-28 19:34:49 +00:00
add_assoc_bool(&directives, "opcache.inherited_hack", ZCG(accel_directives).inherited_hack);
add_assoc_bool(&directives, "opcache.dups_fix", ZCG(accel_directives).ignore_dups);
add_assoc_bool(&directives, "opcache.revalidate_path", ZCG(accel_directives).revalidate_path);
2014-08-25 17:24:55 +00:00
add_assoc_long(&directives, "opcache.log_verbosity_level", ZCG(accel_directives).log_verbosity_level);
add_assoc_long(&directives, "opcache.memory_consumption", ZCG(accel_directives).memory_consumption);
add_assoc_long(&directives, "opcache.interned_strings_buffer",ZCG(accel_directives).interned_strings_buffer);
add_assoc_long(&directives, "opcache.max_accelerated_files", ZCG(accel_directives).max_accelerated_files);
2014-03-28 19:34:49 +00:00
add_assoc_double(&directives, "opcache.max_wasted_percentage", ZCG(accel_directives).max_wasted_percentage);
2014-08-25 17:24:55 +00:00
add_assoc_long(&directives, "opcache.consistency_checks", ZCG(accel_directives).consistency_checks);
add_assoc_long(&directives, "opcache.force_restart_timeout", ZCG(accel_directives).force_restart_timeout);
add_assoc_long(&directives, "opcache.revalidate_freq", ZCG(accel_directives).revalidate_freq);
2014-04-15 11:40:40 +00:00
add_assoc_string(&directives, "opcache.preferred_memory_model", STRING_NOT_NULL(ZCG(accel_directives).memory_model));
add_assoc_string(&directives, "opcache.blacklist_filename", STRING_NOT_NULL(ZCG(accel_directives).user_blacklist_filename));
2014-08-25 17:24:55 +00:00
add_assoc_long(&directives, "opcache.max_file_size", ZCG(accel_directives).max_file_size);
2014-04-15 11:40:40 +00:00
add_assoc_string(&directives, "opcache.error_log", STRING_NOT_NULL(ZCG(accel_directives).error_log));
2014-03-28 19:34:49 +00:00
add_assoc_bool(&directives, "opcache.protect_memory", ZCG(accel_directives).protect_memory);
add_assoc_bool(&directives, "opcache.save_comments", ZCG(accel_directives).save_comments);
add_assoc_bool(&directives, "opcache.enable_file_override", ZCG(accel_directives).file_override_enabled);
2014-08-25 17:24:55 +00:00
add_assoc_long(&directives, "opcache.optimization_level", ZCG(accel_directives).optimization_level);
2016-04-12 07:30:11 +00:00
#ifndef ZEND_WIN32
add_assoc_string(&directives, "opcache.lockfile_path", STRING_NOT_NULL(ZCG(accel_directives).lockfile_path));
2016-04-12 07:30:11 +00:00
#endif
2014-03-28 19:34:49 +00:00
#ifdef HAVE_OPCACHE_FILE_CACHE
add_assoc_string(&directives, "opcache.file_cache", ZCG(accel_directives).file_cache ? ZCG(accel_directives).file_cache : "");
add_assoc_bool(&directives, "opcache.file_cache_only", ZCG(accel_directives).file_cache_only);
add_assoc_bool(&directives, "opcache.file_cache_consistency_checks", ZCG(accel_directives).file_cache_consistency_checks);
#endif
2014-03-28 19:34:49 +00:00
add_assoc_zval(return_value, "directives", &directives);
2013-02-13 12:26:47 +00:00
/*version */
2014-03-28 19:34:49 +00:00
array_init(&version);
2016-05-17 14:16:10 +00:00
add_assoc_string(&version, "version", PHP_VERSION);
2014-04-15 11:40:40 +00:00
add_assoc_string(&version, "opcache_product_name", ACCELERATOR_PRODUCT_NAME);
2014-03-28 19:34:49 +00:00
add_assoc_zval(return_value, "version", &version);
2013-02-13 12:26:47 +00:00
/* blacklist */
2014-03-28 19:34:49 +00:00
array_init(&blacklist);
2014-12-13 22:06:14 +00:00
zend_accel_blacklist_apply(&accel_blacklist, add_blacklist_path, &blacklist);
2014-03-28 19:34:49 +00:00
add_assoc_zval(return_value, "blacklist", &blacklist);
2013-02-13 12:26:47 +00:00
}
/* {{{ proto void accelerator_reset()
Request that the contents of the opcode cache to be reset */
static ZEND_FUNCTION(opcache_reset)
2013-02-13 12:26:47 +00:00
{
if (zend_parse_parameters_none() == FAILURE) {
2013-02-27 18:54:56 +00:00
RETURN_FALSE;
}
2014-12-13 22:06:14 +00:00
if (!validate_api_restriction()) {
RETURN_FALSE;
}
if ((!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled))
#if ENABLE_FILE_CACHE_FALLBACK
&& !fallback_process
#endif
) {
2013-02-13 12:26:47 +00:00
RETURN_FALSE;
}
2014-12-13 22:06:14 +00:00
zend_accel_schedule_restart(ACCEL_RESTART_USER);
2013-02-13 12:26:47 +00:00
RETURN_TRUE;
}
/* {{{ proto void opcache_invalidate(string $script [, bool $force = false])
Invalidates cached script (in necessary or forced) */
static ZEND_FUNCTION(opcache_invalidate)
{
char *script_name;
size_t script_name_len;
zend_bool force = 0;
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &script_name, &script_name_len, &force) == FAILURE) {
return;
}
2014-12-13 22:06:14 +00:00
if (!validate_api_restriction()) {
RETURN_FALSE;
}
2014-12-13 22:06:14 +00:00
if (zend_accel_invalidate(script_name, script_name_len, force) == SUCCESS) {
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}
static ZEND_FUNCTION(opcache_compile_file)
{
char *script_name;
size_t script_name_len;
zend_file_handle handle;
zend_op_array *op_array = NULL;
zend_execute_data *orig_execute_data = NULL;
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &script_name, &script_name_len) == FAILURE) {
return;
}
if (!ZCG(accelerator_enabled)) {
zend_error(E_NOTICE, ACCELERATOR_PRODUCT_NAME " seems to be disabled, can't compile file");
RETURN_FALSE;
}
handle.filename = script_name;
handle.free_filename = 0;
handle.opened_path = NULL;
handle.type = ZEND_HANDLE_FILENAME;
orig_execute_data = EG(current_execute_data);
zend_try {
2014-12-13 22:06:14 +00:00
op_array = persistent_compile_file(&handle, ZEND_INCLUDE);
} zend_catch {
EG(current_execute_data) = orig_execute_data;
zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s", handle.filename);
} zend_end_try();
if(op_array != NULL) {
2014-12-13 22:06:14 +00:00
destroy_op_array(op_array);
efree(op_array);
RETVAL_TRUE;
} else {
RETVAL_FALSE;
}
2014-12-13 22:06:14 +00:00
zend_destroy_file_handle(&handle);
}
/* {{{ proto bool opcache_is_script_cached(string $script)
Return true if the script is cached in OPCache, false if it is not cached or if OPCache is not running. */
static ZEND_FUNCTION(opcache_is_script_cached)
{
zend_string *script_name;
2014-12-13 22:06:14 +00:00
if (!validate_api_restriction()) {
RETURN_FALSE;
}
if (!ZCG(accelerator_enabled)) {
RETURN_FALSE;
}
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &script_name) == FAILURE) {
return;
}
RETURN_BOOL(filename_is_in_cache(script_name));
}