aboutsummaryrefslogtreecommitdiff
path: root/src/os/win32/ngx_files.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-03-30 14:51:51 +0000
committerIgor Sysoev <igor@sysoev.ru>2009-03-30 14:51:51 +0000
commitfadc7a7e810874b95bb934aa107bfe0a795347d3 (patch)
tree433f2fc4d83f67bdd560acf35b82dee0af4ac0fa /src/os/win32/ngx_files.c
parent8017a63cb3952850d0b40b4c95a938a7dbff7fe5 (diff)
downloadnginx-fadc7a7e810874b95bb934aa107bfe0a795347d3.tar.gz
nginx-fadc7a7e810874b95bb934aa107bfe0a795347d3.zip
win32 ngx_open_file() supports utf8 names and NGX_FILE_APPEND
Diffstat (limited to 'src/os/win32/ngx_files.c')
-rw-r--r--src/os/win32/ngx_files.c111
1 files changed, 111 insertions, 0 deletions
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 */
+}