# HG changeset patch # User Igor Sysoev # Date 1238424711 0 # Node ID 64a10d6b97bd841a0f098730dd289c76ad28f2c7 # Parent c9da3e4dc706699080decd622ce3d754b61b9e63 win32 ngx_open_file() supports utf8 names and NGX_FILE_APPEND diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -359,8 +359,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) continue; } - file[i].fd = ngx_open_file(file[i].name.data, NGX_FILE_RDWR, - NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND, + file[i].fd = ngx_open_file(file[i].name.data, + NGX_FILE_RDWR|NGX_FILE_APPEND, + NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS); ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0, @@ -1064,9 +1065,8 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx file[i].pos = file[i].buffer; } - fd = ngx_open_file(file[i].name.data, NGX_FILE_RDWR, - NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND, - NGX_FILE_DEFAULT_ACCESS); + fd = ngx_open_file(file[i].name.data, NGX_FILE_RDWR|NGX_FILE_APPEND, + NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reopen file \"%s\", old:%d new:%d", diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -200,8 +200,10 @@ ngx_log_init(void) ngx_stderr_fileno = GetStdHandle(STD_ERROR_HANDLE); - ngx_stderr.fd = ngx_open_file(NGX_ERROR_LOG_PATH, NGX_FILE_RDWR, - NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND, 0); + ngx_stderr.fd = ngx_open_file((u_char *) NGX_ERROR_LOG_PATH, + NGX_FILE_RDWR|NGX_FILE_APPEND, + NGX_FILE_CREATE_OR_OPEN, + NGX_FILE_DEFAULT_ACCESS); if (ngx_stderr.fd == NGX_INVALID_FILE) { ngx_message_box("nginx", MB_OK, ngx_errno, @@ -210,14 +212,6 @@ ngx_log_init(void) return NULL; } - if (ngx_file_append_mode(ngx_stderr.fd) == NGX_ERROR) { - ngx_message_box("nginx", MB_OK, ngx_errno, - "Could not open error log file: " - ngx_file_append_mode_n " \"" NGX_ERROR_LOG_PATH - "\" failed"); - return NULL; - } - #else ngx_stderr.fd = STDERR_FILENO; diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c --- a/src/core/ngx_open_file_cache.c +++ b/src/core/ngx_open_file_cache.c @@ -466,9 +466,8 @@ ngx_open_and_stat_file(u_char *name, ngx fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); } else { - fd = ngx_open_file(name, NGX_FILE_RDWR, - NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND, - NGX_FILE_DEFAULT_ACCESS); + fd = ngx_open_file(name, NGX_FILE_RDWR|NGX_FILE_APPEND, + NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS); } if (fd == NGX_INVALID_FILE) { diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -44,6 +44,7 @@ typedef int ngx_err_t; #define NGX_EHOSTUNREACH EHOSTUNREACH #define NGX_ENOSYS ENOSYS #define NGX_ECANCELED ECANCELED +#define NGX_EILSEQ EILSEQ #define NGX_ENOMOREFILES 0 diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -48,6 +48,7 @@ typedef DWORD ngx_e #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 --- a/src/os/win32/ngx_files.c +++ b/src/os/win32/ngx_files.c @@ -8,6 +8,38 @@ #include +#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 --- 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