Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions Zend/zend_virtual_cwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,27 @@ CWD_API int virtual_filepath(const char *path, char **filepath) /* {{{ */
}
/* }}} */

#ifndef ZEND_WIN32
/* An absolute path without dot segments doesn't need a per-thread CWD emulation */
static zend_always_inline bool virtual_path_is_direct(const char *path)
{
const char *s = path;

if (*s != '/') {
return false;
}
do {
if (s[1] == '.'
&& (s[2] == '\0' || s[2] == '/'
|| (s[2] == '.' && (s[3] == '\0' || s[3] == '/')))) {
return false;
}
s = strchr(s + 1, '/');
} while (s != NULL);
return true;
}
#endif

CWD_API FILE *virtual_fopen(const char *path, const char *mode) /* {{{ */
{
cwd_state new_state;
Expand All @@ -1310,6 +1331,12 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode) /* {{{ */
return NULL;
}

#ifndef ZEND_WIN32
if (virtual_path_is_direct(path)) {
return fopen(path, mode);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this use php_win32_ioutil_fopen on windows?

@staabm staabm Jul 14, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh its ifNdef ZEND_WIN32 .. nevermind

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I will revisit all these small findings later on Windows

}
#endif

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) {
CWD_STATE_FREE_ERR(&new_state);
Expand All @@ -1333,6 +1360,12 @@ CWD_API int virtual_access(const char *pathname, int mode) /* {{{ */
cwd_state new_state;
int ret;

#ifndef ZEND_WIN32
if (virtual_path_is_direct(pathname)) {
return access(pathname, mode);
}
#endif

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) {
CWD_STATE_FREE_ERR(&new_state);
Expand Down Expand Up @@ -1442,6 +1475,21 @@ CWD_API int virtual_open(const char *path, int flags, ...) /* {{{ */
cwd_state new_state;
int f;

#ifndef ZEND_WIN32
if (virtual_path_is_direct(path)) {
if (flags & O_CREAT) {
mode_t mode;
va_list arg;

va_start(arg, flags);
mode = (mode_t) va_arg(arg, int);
va_end(arg);
return open(path, flags, mode);
}
return open(path, flags);
}
#endif

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH)) {
CWD_STATE_FREE_ERR(&new_state);
Expand Down Expand Up @@ -1533,6 +1581,12 @@ CWD_API int virtual_stat(const char *path, zend_stat_t *buf) /* {{{ */
cwd_state new_state;
int retval;

#ifndef ZEND_WIN32
if (virtual_path_is_direct(path)) {
return php_sys_stat(path, buf);
}
#endif

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
CWD_STATE_FREE_ERR(&new_state);
Expand All @@ -1551,6 +1605,12 @@ CWD_API int virtual_lstat(const char *path, zend_stat_t *buf) /* {{{ */
cwd_state new_state;
int retval;

#ifndef ZEND_WIN32
if (virtual_path_is_direct(path)) {
return php_sys_lstat(path, buf);
}
#endif

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND)) {
CWD_STATE_FREE_ERR(&new_state);
Expand Down Expand Up @@ -1637,6 +1697,12 @@ CWD_API DIR *virtual_opendir(const char *pathname) /* {{{ */
cwd_state new_state;
DIR *retval;

#ifndef ZEND_WIN32
if (virtual_path_is_direct(pathname)) {
return opendir(pathname);
}
#endif

CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH)) {
CWD_STATE_FREE_ERR(&new_state);
Expand Down
Loading