Added clear_realpath_cache and filename parameters to clearstatcache() (Jani,

Arnaud)
[DOC] clearstatcache() now defaults to not affect the realpath cache.
clearstatcache() now takes two optionnal parameters, clear_realpath_cache to
clear the realpath cache (defaults to false), and filename to clear only the
given filename from the cache.
This commit is contained in:
Arnaud Le Blanc 2008-08-07 09:24:04 +00:00
parent 951fe380b3
commit a51e5ebaeb
7 changed files with 89 additions and 17 deletions

View file

@ -1494,7 +1494,9 @@ ZEND_END_ARG_INFO()
#endif
static
ZEND_BEGIN_ARG_INFO(arginfo_clearstatcache, 0)
ZEND_BEGIN_ARG_INFO_EX(arginfo_clearstatcache, 0, 0, 0)
ZEND_ARG_INFO(0, clear_realpath_cache)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
static

View file

@ -780,8 +780,11 @@ PHP_FUNCTION(touch)
/* {{{ php_clear_stat_cache()
*/
PHPAPI void php_clear_stat_cache(TSRMLS_D)
PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
{
/* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
* as it may contains outdated data (e.g. "nlink" for a directory when deleting a file
* in this directory, as shown by lstat_stat_variation9.phpt) */
if (BG(CurrentStatFile)) {
efree(BG(CurrentStatFile));
BG(CurrentStatFile) = NULL;
@ -790,18 +793,40 @@ PHPAPI void php_clear_stat_cache(TSRMLS_D)
efree(BG(CurrentLStatFile));
BG(CurrentLStatFile) = NULL;
}
if (clear_realpath_cache) {
if (filename != NULL) {
realpath_cache_del(filename, filename_len TSRMLS_CC);
} else {
realpath_cache_clean(TSRMLS_C);
}
}
}
/* }}} */
/* {{{ proto void clearstatcache(void)
/* {{{ proto void clearstatcache([bool clear_realpath_cache[, string filename]])
Clear file stat cache */
PHP_FUNCTION(clearstatcache)
{
if (zend_parse_parameters_none() == FAILURE) {
zend_bool clear_realpath_cache = 0;
char *filename = NULL;
zend_uchar filename_type;
int filename_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bt", &clear_realpath_cache, &filename, &filename_len, &filename_type) == FAILURE) {
return;
}
php_clear_stat_cache(TSRMLS_C);
if (filename && filename_type == IS_UNICODE) {
if (FAILURE == php_stream_path_encode(NULL, &filename, &filename_len, (UChar*)filename, filename_len, REPORT_ERRORS, FG(default_context))) {
RETURN_FALSE;
}
}
php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
if (filename && filename_type == IS_UNICODE) {
efree(filename);
}
}
/* }}} */

View file

@ -87,7 +87,7 @@ typedef unsigned int php_stat_len;
typedef int php_stat_len;
#endif
PHPAPI void php_clear_stat_cache(TSRMLS_D);
PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC);
PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value TSRMLS_DC);
PHPAPI void php_u_stat(zend_uchar filename_type, const zstr filename, php_stat_len filename_length, int type, php_stream_context *context, zval *return_value TSRMLS_DC);

View file

@ -19,7 +19,7 @@ function test() {
echo file_get_contents('/tmp/1link')."\n";
unlink('/tmp/1link');
clearstatcache();
clearstatcache(true);
echo file_get_contents('/tmp/1link')."\n";

View file

@ -0,0 +1,45 @@
--TEST--
clearstatcache() optionnal parameters
--SKIPIF--
<?php
if (strncmp(PHP_OS, "WIN", 3) === 0) {
die('skip not for Windows');
}
?>
--FILE--
<?php
@rmdir(__FILE__ . "_dir1");
@rmdir(__FILE__ . "_dir2");
@unlink(__FILE__ . "_link1");
@unlink(__FILE__ . "_link2");
mkdir(__FILE__ . "_dir1");
mkdir(__FILE__ . "_dir2");
symlink(__FILE__ . "_link1", __FILE__ . "_link2");
symlink(__FILE__ . "_dir1", __FILE__ . "_link1");
var_dump(realpath(__FILE__ . "_link2"));
passthru("rm -f " . escapeshellarg(__FILE__ . "_link1"));
var_dump(realpath(__FILE__ . "_link2"));
clearstatcache(false);
var_dump(realpath(__FILE__ . "_link2"));
clearstatcache(true, "/foo/bar");
var_dump(realpath(__FILE__ . "_link2"));
clearstatcache(true, __FILE__ . "_link2");
var_dump(realpath(__FILE__ . "_link2"));
?>
--CLEAN--
<?php
@rmdir(__FILE__ . "_dir1");
@rmdir(__FILE__ . "_dir2");
@unlink(__FILE__ . "_link1");
@unlink(__FILE__ . "_link2");
?>
--EXPECTF--
%unicode|string%(%d) "%s_dir1"
%unicode|string%(%d) "%s_dir1"
%unicode|string%(%d) "%s_dir1"
%unicode|string%(%d) "%s_dir1"
bool(false)

View file

@ -3,17 +3,17 @@ Test clearstatcache() function: error conditions
--FILE--
<?php
/*
Prototype: void clearstatcache (void);
Prototype: void clearstatcache ([bool clear_realpath_cache[, filename]]);
Description: clears files status cache
*/
echo "*** Testing clearstatcache() function: error conditions ***\n";
var_dump( clearstatcache("file") ); //No.of args more than expected
var_dump( clearstatcache(0, "/foo/bar", 1) ); //No.of args more than expected
echo "*** Done ***\n";
?>
--EXPECTF--
*** Testing clearstatcache() function: error conditions ***
Warning: clearstatcache() expects exactly 0 parameters, 1 given in %s on line %d
Warning: clearstatcache() expects at most 2 parameters, 3 given in %s on line %d
NULL
*** Done ***

View file

@ -1025,8 +1025,8 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, char *url, int op
return 0;
}
/* Clear stat cache */
php_clear_stat_cache(TSRMLS_C);
/* Clear stat cache (and realpath cache) */
php_clear_stat_cache(1, NULL, 0 TSRMLS_CC);
return 1;
}
@ -1092,8 +1092,8 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, c
return 0;
}
/* Clear stat cache */
php_clear_stat_cache(TSRMLS_C);
/* Clear stat cache (and realpath cache) */
php_clear_stat_cache(1, NULL, 0 TSRMLS_CC);
return 1;
}
@ -1202,8 +1202,8 @@ static int php_plain_files_rmdir(php_stream_wrapper *wrapper, char *url, int opt
return 0;
}
/* Clear stat cache */
php_clear_stat_cache(TSRMLS_C);
/* Clear stat cache (and realpath cache) */
php_clear_stat_cache(1, NULL, 0 TSRMLS_CC);
return 1;
}