Hi Greg,
In your second patch you forgot "break", so it couldn't work.
I don't see any reason in second patch at all, because you call
php_resolve_patch() from _php_stream_open_wrapper_ex() anyway.
The bad thing with the first part that it calls realpath() function
twice for each include("relative_path.php") and it makes several
file-system accesses (look into `strace ... 2>&1| grep lstat`). With
your patch I see 6 syscalls more.
So I would prefer my patch that is more efficient for regular files.
The same patch with fixed white-spaces is attached.
Thanks. Dmitry.
Gregory Beaver wrote:
Dmitry Stogov wrote:
Hi Greg,
I've fixed your patch to work with all functions (fopen,
file_get_contente).
Please verify it with ext/phar and then I'll commit it.
Thanks. Dmitry.
Gregory Beaver wrote:
Hi,
Please look at the stream wrappers in include_path patch I posted
last week.
Thanks,
Greg
Hi Dmitry,
the patch has a few major problems and a few minor ones. First off,
there are spaces instead of tabs, which is not a huge deal, I've
corrected that in the attached patch.
It is, however, logically void to do stream wrapper operations in
plain_wrapper.c. I removed that code entirely. Instead, the path
resolve is now done in php_stream_open_wrapper_ex where it belongs,
before determining which stream wrapper to open. This will result in a
double call to the function when calling include, but because the 2nd
call will simply return after determining it has received a full path.
I've attached 2 patches (apparently, Zend is not included in cvs diff -u
of php5), 1 for adding path resolution to include/require (this is a
significant performance improvement over the existing code). The second
patch adds stream wrapper support to both php_resolve_path and
_php_stream_open_wrapper_ex, which automatically gives stream wrapper in
include_path support to all current and future functions that use
include_path.
Greg
Index: main/fopen_wrappers.c
===================================================================
RCS file: /repository/php-src/main/fopen_wrappers.c,v
retrieving revision 1.175.2.3.2.13.2.8
diff -u -p -d -r1.175.2.3.2.13.2.8 fopen_wrappers.c
--- main/fopen_wrappers.c 13 Mar 2008 14:09:54 -0000
1.175.2.3.2.13.2.8
+++ main/fopen_wrappers.c 21 Mar 2008 09:09:03 -0000
@@ -473,7 +473,15 @@ PHPAPI char *php_resolve_path(const char
ptr = path;
while (ptr && *ptr) {
- end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
+ /* Check for stream wrapper */
+ int is_stream_wrapper = 0;
+
+ for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p
== '.'; p++);
+ if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] ==
'/')) {
+ p += 2;
+ is_stream_wrapper = 1;
+ }
+ end = strchr(p, DEFAULT_DIR_SEPARATOR);
if (end) {
if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) {
ptr = end + 1;
@@ -494,6 +502,25 @@ PHPAPI char *php_resolve_path(const char
memcpy(trypath+len+1, filename, filename_length+1);
ptr = NULL;
}
+ if (is_stream_wrapper) {
+ char *actual;
+ php_stream_wrapper *wrapper =
php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE
TSRMLS_CC);
+
+ if (!wrapper) {
+ continue;
+ } else if (wrapper == &php_plain_files_wrapper) {
+ strncpy(trypath, actual, MAXPATHLEN);
+ } else {
+ if (wrapper->wops->url_stat) {
+ php_stream_statbuf ssb;
+
+ if (SUCCESS ==
wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
+ return estrdup(trypath);
+ }
+ }
+ continue;
+ }
+ }
if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) {
return estrdup(resolved_path);
}
@@ -511,6 +538,29 @@ PHPAPI char *php_resolve_path(const char
exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) {
memcpy(trypath, exec_fname, exec_fname_length + 1);
memcpy(trypath+exec_fname_length + 1, filename,
filename_length+1);
+
+ /* Check for stream wrapper */
+ for (p = trypath; isalnum((int)*p) || *p == '+' || *p
== '-' || *p == '.'; p++);
+ if ((*p == ':') && (p - trypath > 1) && (p[1] == '/')
&& (p[2] == '/')) {
+ char *actual;
+ php_stream_wrapper *wrapper =
php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE
TSRMLS_CC);
+
+ if (!wrapper) {
+ return NULL;
+ } else if (wrapper == &php_plain_files_wrapper)
{
+ strncpy(trypath, actual, MAXPATHLEN);
+ } else {
+ if (wrapper->wops->url_stat) {
+ php_stream_statbuf ssb;
+
+ if (SUCCESS ==
wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
+ return estrdup(trypath);
+ }
+ }
+ return NULL;
+ }
+ }
+
if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) {
return estrdup(resolved_path);
}
Index: main/streams/plain_wrapper.c
===================================================================
RCS file: /repository/php-src/main/streams/plain_wrapper.c,v
retrieving revision 1.52.2.6.2.23.2.5
diff -u -p -d -r1.52.2.6.2.23.2.5 plain_wrapper.c
--- main/streams/plain_wrapper.c 31 Dec 2007 07:17:17 -0000
1.52.2.6.2.23.2.5
+++ main/streams/plain_wrapper.c 21 Mar 2008 09:09:03 -0000
@@ -1254,7 +1254,7 @@ php_stream_wrapper php_plain_files_wrapp
PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode,
char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC)
{
/* code ripped off from fopen_wrappers.c */
- char *pathbuf, *ptr, *end;
+ char *pathbuf, *ptr, *end, *p;
char *exec_fname;
char trypath[MAXPATHLEN];
struct stat sb;
@@ -1380,7 +1380,16 @@ not_relative_path:
ptr = pathbuf;
while (ptr && *ptr) {
- end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
+ /* Check for stream wrapper */
+ int is_stream_wrapper = 0;
+
+ for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p
== '.'; p++);
+ if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] ==
'/')) {
+ p += 2;
+ is_stream_wrapper = 1;
+ }
+
+ end = strchr(p, DEFAULT_DIR_SEPARATOR);
if (end != NULL) {
*end = '\0';
end++;
@@ -1390,6 +1399,27 @@ not_relative_path:
}
snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename);
+ if (is_stream_wrapper) {
+ char *actual;
+ php_stream_wrapper *wrapper =
php_stream_locate_url_wrapper(trypath, &actual, options TSRMLS_CC);
+
+ if (!wrapper) {
+ continue;
+ } else if (wrapper == &php_plain_files_wrapper) {
+ strncpy(trypath, actual, MAXPATHLEN);
+ } else {
+ stream = php_stream_open_wrapper(trypath, mode,
options & ~REPORT_ERRORS, opened_path);
+ if (stream) {
+ if (opened_path && !*opened_path) {
+ *opened_path = estrdup(trypath);
+ }
+ efree(pathbuf);
+ return stream;
+ }
+ continue;
+ }
+ }
+
if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) &&
php_check_open_basedir_ex(trypath, 0 TSRMLS_CC)) {
goto stream_skip;
}
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php