]> granicus.if.org Git - php/commitdiff
Revamp fopen implementation, rely on open
authorAnatol Belski <ab@php.net>
Sat, 9 Dec 2017 10:45:21 +0000 (11:45 +0100)
committerAnatol Belski <ab@php.net>
Sat, 9 Dec 2017 10:58:17 +0000 (11:58 +0100)
win32/ioutil.c
win32/ioutil.h

index 562767bf7c37066d14dcf39443d96b7b12b4b6fd..c33591354fc2f39e69a11d3523a5f099b05c748f 100644 (file)
@@ -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 <pathcch.h>
 
@@ -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
index da223f430fc3f13b101d3021c2628dc0dbc3fa53..f3a72b346e1c535932d043f85cc87ed1e0098f6c 100644 (file)
@@ -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);