From: Anatol Belski Date: Sat, 9 Dec 2017 10:45:21 +0000 (+0100) Subject: Revamp fopen implementation, rely on open X-Git-Tag: php-7.3.0alpha1~844 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f3fd860e244945cdc7add0d8c1cbfbde7382c4fe;p=php Revamp fopen implementation, rely on open --- diff --git a/win32/ioutil.c b/win32/ioutil.c index 562767bf7c..c33591354f 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -57,6 +57,7 @@ #include "win32/time.h" #include "win32/ioutil.h" #include "win32/codepage.h" +#include "main/streams/php_stream_plain_wrapper.h" #include @@ -665,6 +666,46 @@ PW32IO int php_win32_ioutil_access_w(const wchar_t *path, mode_t mode) return 0; }/*}}}*/ +PW32IO FILE *php_win32_ioutil_fopen_w(const wchar_t *path, const wchar_t *mode) +{/*{{{*/ + FILE *ret; + char *modea; + int err = 0, fd, flags; + + PHP_WIN32_IOUTIL_CHECK_PATH_W(path, NULL, 0) + + /* Using the converter from streams, char only. */ + modea = php_win32_cp_w_to_any(mode); + if (!modea) { + err = GetLastError(); + SET_ERRNO_FROM_WIN32_CODE(err); + return NULL; + } + if (SUCCESS != php_stream_parse_fopen_modes(modea, &flags)) { + free(modea); + SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); + return NULL; + } + free(modea); + + fd = php_win32_ioutil_open_w(path, flags, 0666); + if (0 > fd) { + err = GetLastError(); + SET_ERRNO_FROM_WIN32_CODE(err); + return NULL; + } + + ret = _wfdopen(fd, mode); + if (!ret) { + err = GetLastError(); + php_win32_ioutil_close(fd); + SET_ERRNO_FROM_WIN32_CODE(err); + return NULL; + } + + return ret; +}/*}}}*/ + /* * Local variables: * tab-width: 4 diff --git a/win32/ioutil.h b/win32/ioutil.h index da223f430f..f3a72b346e 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -257,6 +257,7 @@ PW32IO wchar_t *php_win32_ioutil_getcwd_w(wchar_t *buf, size_t len); PW32IO int php_win32_ioutil_unlink_w(const wchar_t *path); PW32IO int php_win32_ioutil_access_w(const wchar_t *path, mode_t mode); PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode); +PW32IO FILE *php_win32_ioutil_fopen_w(const wchar_t *path, const wchar_t *mode); __forceinline static int php_win32_ioutil_access(const char *path, mode_t mode) {/*{{{*/ @@ -369,17 +370,13 @@ __forceinline static int php_win32_ioutil_rmdir(const char *path) return ret; }/*}}}*/ -/* This needs to be improved once long path support is implemented. Use ioutil_open() and then -fdopen() might be the way, if we learn how to convert the mode options (maybe grab the routine - from the streams). That will allow to split for _a and _w. */ __forceinline static FILE *php_win32_ioutil_fopen(const char *patha, const char *modea) {/*{{{*/ FILE *ret; - wchar_t *pathw; wchar_t *modew; int err = 0; - pathw = php_win32_ioutil_any_to_w(patha); + PHP_WIN32_IOUTIL_INIT_W(patha) if (!pathw) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; @@ -387,23 +384,25 @@ __forceinline static FILE *php_win32_ioutil_fopen(const char *patha, const char PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, NULL, 1) - modew = php_win32_ioutil_ascii_to_w(modea); - if (!modew) { - free(pathw); + modew = php_win32_cp_ascii_to_w(modea); + if (!patha) { + PHP_WIN32_IOUTIL_CLEANUP_W() SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } - ret = _wfopen(pathw, modew); + ret = php_win32_ioutil_fopen_w(pathw, modew); if (!ret) { - _get_errno(&err); + err = GetLastError(); + PHP_WIN32_IOUTIL_CLEANUP_W() + free(modew); + SET_ERRNO_FROM_WIN32_CODE(err); + return NULL; } - free(pathw); + + PHP_WIN32_IOUTIL_CLEANUP_W() free(modew); - if (!ret) { - _set_errno(err); - } return ret; }/*}}}*/ @@ -548,9 +547,9 @@ __forceinline static int php_win32_ioutil_chmod(const char *patha, int mode) __forceinline static int php_win32_ioutil_mkdir(const char *path, mode_t mode) {/*{{{*/ int ret; - wchar_t *pathw = php_win32_ioutil_any_to_w(path); DWORD err = 0; + PHP_WIN32_IOUTIL_INIT_W(path) if (!pathw) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return -1; @@ -561,7 +560,7 @@ __forceinline static int php_win32_ioutil_mkdir(const char *path, mode_t mode) err = GetLastError(); } - free(pathw); + PHP_WIN32_IOUTIL_CLEANUP_W() if (0 > ret) { SET_ERRNO_FROM_WIN32_CODE(err);