summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Le Blanc <lbarnaud@php.net>2008-08-07 09:25:33 +0000
committerArnaud Le Blanc <lbarnaud@php.net>2008-08-07 09:25:33 +0000
commitc93fbf629bb4ad063e9850984f039970b1d3b7c2 (patch)
tree5a76c3c7c1c0549062a607137715b3352416cec3
parent53a957e5f8d7d0b67aa1b7f7bdf629784a51debd (diff)
downloadphp-git-c93fbf629bb4ad063e9850984f039970b1d3b7c2.tar.gz
MFH:
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.
-rw-r--r--NEWS2
-rw-r--r--ext/standard/basic_functions.c4
-rw-r--r--ext/standard/filestat.c24
-rw-r--r--ext/standard/php_filestat.h2
-rwxr-xr-xext/standard/tests/file/bug39367.phpt2
-rw-r--r--ext/standard/tests/file/clearstatcache_001.phpt45
-rw-r--r--ext/standard/tests/file/clearstatcache_error.phpt6
-rw-r--r--main/streams/plain_wrapper.c12
8 files changed, 80 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index 4c2e7f61cf..c8699034b1 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 200?, PHP 5.3.0 Alpha 2
- Removed shebang line check from CGI sapi (it is checked by scanner) (Dmitry)
+- Added clear_realpath_cache and filename parameters to clearstatcache() (Jani,
+ Arnaud)
- Added litespeed SAPI module. (George Wang)
- Added ext/hash support to ext/session's ID generator. (Sara)
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 205c49217b..b5c078a24b 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -1507,7 +1507,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
diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c
index 2707c50da4..3ec931c42d 100644
--- a/ext/standard/filestat.c
+++ b/ext/standard/filestat.c
@@ -712,8 +712,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;
@@ -722,18 +725,29 @@ PHPAPI void php_clear_stat_cache(TSRMLS_D)
efree(BG(CurrentLStatFile));
BG(CurrentLStatFile) = NULL;
}
- realpath_cache_clean(TSRMLS_C);
+ 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;
+ int filename_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &clear_realpath_cache, &filename, &filename_len) == FAILURE) {
return;
}
- php_clear_stat_cache(TSRMLS_C);
+
+ php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
}
/* }}} */
diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h
index c4eaca953a..e9dcfddaa0 100644
--- a/ext/standard/php_filestat.h
+++ b/ext/standard/php_filestat.h
@@ -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);
/* Switches for various filestat functions: */
diff --git a/ext/standard/tests/file/bug39367.phpt b/ext/standard/tests/file/bug39367.phpt
index 01fb5e8c84..f3e79fcf5e 100755
--- a/ext/standard/tests/file/bug39367.phpt
+++ b/ext/standard/tests/file/bug39367.phpt
@@ -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";
diff --git a/ext/standard/tests/file/clearstatcache_001.phpt b/ext/standard/tests/file/clearstatcache_001.phpt
new file mode 100644
index 0000000000..6177116fab
--- /dev/null
+++ b/ext/standard/tests/file/clearstatcache_001.phpt
@@ -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)
diff --git a/ext/standard/tests/file/clearstatcache_error.phpt b/ext/standard/tests/file/clearstatcache_error.phpt
index 1ebb08888e..ee7d1af18c 100644
--- a/ext/standard/tests/file/clearstatcache_error.phpt
+++ b/ext/standard/tests/file/clearstatcache_error.phpt
@@ -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 ***
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index ace2dc38fd..6be46df215 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -1039,8 +1039,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;
}
@@ -1111,8 +1111,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;
}
@@ -1225,8 +1225,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;
}