diff options
Diffstat (limited to 'src/os/win32')
| -rw-r--r-- | src/os/win32/ngx_errno.h | 1 | ||||
| -rw-r--r-- | src/os/win32/ngx_files.c | 111 | ||||
| -rw-r--r-- | src/os/win32/ngx_files.h | 12 |
3 files changed, 115 insertions, 9 deletions
diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h index 58cbbf402..75ae73f5d 100644 --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -48,6 +48,7 @@ typedef DWORD ngx_err_t; #define NGX_EHOSTDOWN WSAEHOSTDOWN #define NGX_EHOSTUNREACH WSAEHOSTUNREACH #define NGX_ENOMOREFILES ERROR_NO_MORE_FILES +#define NGX_EILSEQ ERROR_NO_UNICODE_TRANSLATION #define NGX_EALREADY WSAEALREADY #define NGX_EINVAL WSAEINVAL diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c index afe31b9a0..f20b47973 100644 --- a/src/os/win32/ngx_files.c +++ b/src/os/win32/ngx_files.c @@ -8,6 +8,38 @@ #include <ngx_core.h> +#define NGX_UTF16_BUFLEN 256 + +static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len); + + +/* FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory */ + +ngx_fd_t +ngx_open_file(u_char *name, u_long mode, u_long create, u_long access) +{ + u_short *u; + ngx_fd_t fd; + u_short utf16[NGX_UTF16_BUFLEN]; + + u = ngx_utf8_to_utf16(utf16, name, NGX_UTF16_BUFLEN); + + if (u == NULL) { + return INVALID_HANDLE_VALUE; + } + + fd = CreateFileW(u, mode, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL); + + if (u != utf16) { + ngx_free(u); + } + + return fd; +} + + ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { @@ -529,3 +561,82 @@ ngx_fs_bsize(u_char *name) return sc * bs; } + + +static u_short * +ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len) +{ + u_char *p; + u_short *u, *last; + uint32_t n; + + p = utf8; + u = utf16; + last = utf16 + len; + + while (u < last) { + + if (*p < 0x80) { + *u = (u_short) *p; + + if (*p == 0) { + return utf16; + } + + u++; + p++; + + continue; + } + + n = ngx_utf8_decode(&p, 4); + + if (n > 0xffff) { + free(utf16); + ngx_set_errno(NGX_EILSEQ); + return NULL; + } + + *u++ = (u_short) n; + } + + /* the given buffer is not enough, allocate a new one */ + + u = malloc(((p - utf8) + ngx_strlen(p) + 1) * sizeof(u_short)); + if (u == NULL) { + return NULL; + } + + ngx_memcpy(u, utf16, len * 2); + + utf16 = u; + u += len; + + for ( ;; ) { + + if (*p < 0x80) { + *u = (u_short) *p; + + if (*p == 0) { + return utf16; + } + + u++; + p++; + + continue; + } + + n = ngx_utf8_decode(&p, 4); + + if (n > 0xffff) { + free(utf16); + ngx_set_errno(NGX_EILSEQ); + return NULL; + } + + *u++ = (u_short) n; + } + + /* unreachable */ +} diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h index 47a76611b..5efd0fe1a 100644 --- a/src/os/win32/ngx_files.h +++ b/src/os/win32/ngx_files.h @@ -57,22 +57,16 @@ typedef struct { #define NGX_FILE_ERROR 0 -/* - * FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory - */ - -#define ngx_open_file(name, mode, create, access) \ - CreateFile((const char *) name, mode, \ - FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \ - NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL) +ngx_fd_t ngx_open_file(u_char *name, u_long mode, u_long create, u_long access); #define ngx_open_file_n "CreateFile()" #define NGX_FILE_RDONLY GENERIC_READ #define NGX_FILE_WRONLY GENERIC_WRITE #define NGX_FILE_RDWR GENERIC_READ|GENERIC_WRITE +#define NGX_FILE_APPEND FILE_APPEND_DATA|SYNCHRONIZE + #define NGX_FILE_CREATE_OR_OPEN OPEN_ALWAYS #define NGX_FILE_OPEN OPEN_EXISTING -#define NGX_FILE_APPEND 0 #define NGX_FILE_DEFAULT_ACCESS 0 #define NGX_FILE_OWNER_ACCESS 0 |
