# HG changeset patch # User Igor Sysoev # Date 1069019382 0 # Node ID c1f3a3c7c5db51ce28d461fe442c4984e7db56ff # Parent d5f50cefc32255564942561ce62f2dada0b9017f nginx-0.0.1-2003-11-17-00:49:42 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -97,7 +97,9 @@ int main(int argc, char *const *argv) return 1; } +#if 0 stub_init(log); +#endif ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { @@ -229,8 +231,6 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ break; } } - - return 0; } @@ -513,7 +513,7 @@ ngx_log_debug(log, "OPEN: %d:%s" _ file[ ngx_cleaner_event.event_handler = ngx_clean_old_cycles; ngx_cleaner_event.log = cycle->log; ngx_cleaner_event.data = &dumb; - dumb.fd = -1; + dumb.fd = (ngx_socket_t) -1; } ngx_temp_pool->log = cycle->log; @@ -541,11 +541,14 @@ static int ngx_open_listening_sockets(ng ngx_listening_t *ls; reuseaddr = 1; +#if (NGX_SUPPRESS_WARN) + failed = 0; +#endif /* TODO: times configurable */ for (times = 10; times; times--) { - failed = 0; + failed = 0; /* for each listening socket */ @@ -597,6 +600,16 @@ static int ngx_open_listening_sockets(ng /* TODO: close on exit */ + if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { + if (ngx_nonblocking(s) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_nonblocking_n " %s failed", + ls[i].addr_text.data); + return NGX_ERROR; + } + } + +#if 0 if (ls[i].nonblocking) { if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, @@ -605,6 +618,7 @@ static int ngx_open_listening_sockets(ng return NGX_ERROR; } } +#endif if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { err = ngx_socket_errno; diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -55,9 +55,9 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)), NGX_CONF_ERROR); - if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) { + if (ngx_fd_info(fd, &cf->conf_file->file.info) == -1) { ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, - ngx_stat_fd_n " %s failed", filename->data); + ngx_fd_info_n " %s failed", filename->data); } ngx_test_null(cf->conf_file->hunk, @@ -310,7 +310,7 @@ ngx_log_debug(cf->log, "TOKEN START"); if (h->pos >= h->last) { if (cf->conf_file->file.offset - >= ngx_file_size((&cf->conf_file->file.info))) { + >= ngx_file_size(&cf->conf_file->file.info)) { return NGX_CONF_FILE_DONE; } diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -2,12 +2,6 @@ #define _NGX_CORE_H_INCLUDED_ -#include -#include -#include -#include -#include - typedef struct ngx_module_s ngx_module_t; typedef struct ngx_conf_s ngx_conf_t; typedef struct ngx_cycle_s ngx_cycle_t; @@ -18,6 +12,11 @@ typedef struct ngx_file_s ngx_fil typedef struct ngx_event_s ngx_event_t; typedef struct ngx_connection_s ngx_connection_t; + +#include +#include +#include +#include #include #include #include @@ -25,6 +24,7 @@ typedef struct ngx_connection_s ngx_con #include #include #include +#include #include #include #include diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -86,7 +86,7 @@ ngx_log_debug(file->log, "temp fd: %d" _ } if (err != NGX_ENOENT -#if (WIN32_NEED_TEST) +#if (WIN32) && err != NGX_ENOTDIR #endif ) { @@ -149,11 +149,12 @@ int ngx_create_path(ngx_file_t *file, ng ngx_log_debug(file->log, "temp: %s" _ file->name.data); - if (ngx_mkdir(file->name.data) == NGX_FILE_ERROR) { + if (ngx_create_dir(file->name.data) == NGX_FILE_ERROR) { err = ngx_errno; if (err != NGX_EEXIST) { ngx_log_error(NGX_LOG_CRIT, file->log, err, - ngx_mkdir_n " \"%s\" failed", file->name.data); + ngx_create_dir_n " \"%s\" failed", + file->name.data); return NGX_ERROR; } } diff --git a/src/core/ngx_garbage_collector.c b/src/core/ngx_garbage_collector.c --- a/src/core/ngx_garbage_collector.c +++ b/src/core/ngx_garbage_collector.c @@ -6,7 +6,11 @@ typedef struct ngx_gc_s ngx_gc_t; typedef int (*ngx_gc_handler_pt) (ngx_gc_t *ctx, ngx_str_t *name, - ngx_file_info_t *fi); + ngx_dir_t *dir); + + +static int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, + ngx_dir_t *dir); struct ngx_gc_s { ngx_path_t *path; @@ -78,6 +82,7 @@ void stub_init(ngx_log_t *log) ctx->path = &path; ctx->log = log; + ctx->handler = ngx_garbage_collector_temp_handler; ngx_collect_garbage(ctx, &path.name, 0); } @@ -85,76 +90,85 @@ void stub_init(ngx_log_t *log) static int ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, int level) { - int nlen; - char *last; - ngx_str_t fname; - ngx_dir_t *dir; - ngx_dirent_t *de; - ngx_file_info_t fi; + int rc, len; + char *last; + ngx_err_t err; + ngx_str_t fname, buf; + ngx_dir_t dir; - fname.len = 0; + buf.len = 0; -ngx_log_debug(ctx->log, "dir %s" _ dname->data); +ngx_log_debug(ctx->log, "dir '%s':%d" _ dname->data _ dname->len); - dir = ngx_open_dir(dname->data); - - if (dir == NULL) { - ngx_log_error(NGX_LOG_ERR, ctx->log, ngx_errno, - ngx_open_dir_n " \"%s\" failed", dname->data); + if (ngx_open_dir(dname, &dir) == NGX_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_open_dir_n " \"%s\" failed", dname->data); return NGX_ERROR; } for ( ;; ) { - de = ngx_read_dir(dir); + ngx_set_errno(0); + if (ngx_read_dir(&dir) == NGX_ERROR) { + err = ngx_errno; - if (de == NULL) { - if (fname.len) { - ngx_free(fname.data); + if (err != NGX_ENOMOREFILES) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, err, + ngx_read_dir_n " \"%s\" failed", dname->data); + rc = NGX_ERROR; + + } else { + rc = NGX_OK; } + break; } -ngx_log_debug(ctx->log, "file %s" _ de->d_name); + len = ngx_de_namelen(&dir); -#ifdef __FreeBSD__ - nlen = de->d_namlen; -#else - nlen = ngx_strlen(de->d_name); -#endif +ngx_log_debug(ctx->log, "name '%s':%d" _ ngx_de_name(&dir) _ len); - if (nlen == 1 && de->d_name[0] == '.') { + if (len == 1 && ngx_de_name(&dir)[0] == '.') { continue; } - if (nlen == 2 && de->d_name[0] == '.' && de->d_name[1] == '.') { + if (len == 2 + && ngx_de_name(&dir)[0] == '.' + && ngx_de_name(&dir)[1] == '.') + { continue; } - if (dname->len + 1 + nlen > fname.len) { - if (fname.len) { - ngx_free(fname.data); + fname.len = dname->len + 1+ len; + + if (fname.len + NGX_DIR_MASK_LEN > buf.len) { + + if (buf.len) { + ngx_free(buf.data); } - fname.len = dname->len + 1 + nlen; + buf.len = dname->len + 1 + len + NGX_DIR_MASK_LEN; - if (!(fname.data = ngx_alloc(fname.len + 1, ctx->log))) { + if (!(buf.data = ngx_alloc(buf.len + 1, ctx->log))) { return NGX_ABORT; } } - last = ngx_cpymem(fname.data, dname->data, dname->len); + last = ngx_cpymem(buf.data, dname->data, dname->len); *last++ = '/'; - ngx_memcpy(last, de->d_name, nlen + 1); + ngx_memcpy(last, ngx_de_name(&dir), len + 1); + fname.data = buf.data; + +ngx_log_debug(ctx->log, "path %s" _ fname.data); -ngx_log_debug(ctx->log, "de %s" _ fname.data); - - if (ngx_file_type(fname.data, &fi) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, - ngx_file_type_n " \"%s\" failed", fname.data); - continue; + if (!dir.info_valid) { + if (ngx_de_info(fname.data, &dir) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_de_info_n " \"%s\" failed", fname.data); + continue; + } } - if (ngx_is_dir((&fi))) { + if (ngx_de_is_dir(&dir)) { ngx_log_debug(ctx->log, "enter %s" _ fname.data); @@ -162,12 +176,14 @@ ngx_log_debug(ctx->log, "enter %s" _ fna /* there can not be directory on the last level */ || level == NGX_MAX_PATH_LEVEL /* an directory from the old path hierarchy */ - || nlen != ctx->path->level[level]) + || len != ctx->path->level[level]) { if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) { return NGX_ABORT; } + fname.data[fname.len] = '\0'; + ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, "delete old hierachy directory \"%s\"", fname.data); @@ -178,7 +194,7 @@ ngx_log_debug(ctx->log, "enter %s" _ fna fname.data); } else { ctx->deleted++; - ctx->freed += ngx_file_size((&fi)); + ctx->freed += ngx_de_size(&dir); } continue; @@ -188,7 +204,9 @@ ngx_log_debug(ctx->log, "enter %s" _ fna return NGX_ABORT; } - } else if (ngx_is_file((&fi))) { + } else if (ngx_de_is_file(&dir)) { + +ngx_log_debug(ctx->log, "file %s" _ fname.data); if (level == -1 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0)) @@ -199,13 +217,13 @@ ngx_log_debug(ctx->log, "enter %s" _ fna fname.data); } else { ctx->deleted++; - ctx->freed += ngx_file_size((&fi)); + ctx->freed += ngx_de_size(&dir); } continue; } - if (ctx->handler(ctx, &fname, &fi) == NGX_ABORT) { + if (ctx->handler(ctx, &fname, &dir) == NGX_ABORT) { return NGX_ABORT; } @@ -218,17 +236,26 @@ ngx_log_debug(ctx->log, "enter %s" _ fna ngx_delete_file_n " \"%s\" failed", fname.data); } else { ctx->deleted++; - ctx->freed += ngx_file_size((&fi)); + ctx->freed += ngx_de_size(&dir); } } } - return NGX_OK; + if (buf.len) { + ngx_free(buf.data); + } + + if (ngx_close_dir(&dir) == NGX_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_close_dir_n " \"%s\" failed", fname.data); + } + + return rc; } -int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, - ngx_file_info_t *fi) +static int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, + ngx_dir_t *dir) { /* * we use mtime only and do not use atime because: @@ -237,7 +264,7 @@ int ngx_garbage_collector_temp_handler(n * Unices have mount option "noatime" */ - if (ngx_cached_time - ngx_file_mtime(fi) < 3600) { + if (ngx_cached_time - ngx_de_mtime(dir) < 3600) { return NGX_OK; } @@ -251,6 +278,6 @@ int ngx_garbage_collector_temp_handler(n } ctx->deleted++; - ctx->freed += ngx_file_size(fi); + ctx->freed += ngx_de_size(dir); return NGX_OK; } 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 @@ -65,7 +65,7 @@ void ngx_log_error_core(int level, ngx_l va_list args; #endif #if (WIN32) - u_int written; + u_long written; #endif if (log->file->fd == NGX_INVALID_FILE) { diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -139,8 +139,6 @@ void ngx_log_error_core(int level, ngx_l #else /* NO VARIADIC MACROS */ -#include - #if (NGX_DEBUG) #define ngx_log_debug(log, text) \ if (log->log_level == NGX_LOG_DEBUG) \ diff --git a/src/event/modules/ngx_iocp_module.c b/src/event/modules/ngx_iocp_module.c --- a/src/event/modules/ngx_iocp_module.c +++ b/src/event/modules/ngx_iocp_module.c @@ -110,7 +110,7 @@ static int ngx_iocp_init(ngx_cycle_t *cy return NGX_ERROR; } - ngx_io = ngx_os_io; + ngx_io = ngx_iocp_io; ngx_event_actions = ngx_iocp_module_ctx.actions; @@ -233,16 +233,19 @@ static int ngx_iocp_process_events(ngx_l ngx_log_debug(log, "iocp ev: %08x" _ ev); switch (key) { + case NGX_IOCP_ACCEPT: + if (bytes) { + ev->ready = 1; + } + break; + case NGX_IOCP_IO: ev->complete = 1; ev->ready = 1; break; - case NGX_IOCP_ACCEPT: - if (bytes) { - ev->ready = 1; - } - break; + case NGX_IOCP_CONNECT: + ev->ready = 1; } ev->available = bytes; diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -460,7 +460,7 @@ static int ngx_kqueue_process_events(ngx default: ngx_log_error(NGX_LOG_ALERT, log, 0, - "unknown kevent filter %d" _ event_list[i].filter); + "unexpected kevent filter %d" _ event_list[i].filter); } } diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -265,9 +265,6 @@ static int ngx_select_process_events(ngx timer = ngx_event_find_timer(); if (timer) { - tv.tv_sec = timer / 1000; - tv.tv_usec = (timer % 1000) * 1000; - tp = &tv; #if (HAVE_SELECT_CHANGE_TIMEOUT) delta = 0; #else @@ -275,10 +272,13 @@ static int ngx_select_process_events(ngx delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; #endif + tv.tv_sec = timer / 1000; + tv.tv_usec = (timer % 1000) * 1000; + tp = &tv; + } else { - timer = 0; + delta = 0; tp = NULL; - delta = 0; } #if !(WIN32) diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -277,6 +277,7 @@ extern ngx_event_actions_t ngx_event_a #if (HAVE_IOCP_EVENT) #define NGX_IOCP_ACCEPT 0 #define NGX_IOCP_IO 1 +#define NGX_IOCP_CONNECT 2 #endif diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -180,8 +180,8 @@ int ngx_event_connect_peer(ngx_peer_conn ngx_memzero(&addr, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; + addr.sin_port = peer->port; addr.sin_addr.s_addr = peer->addr; - addr.sin_port = peer->port; ngx_log_debug(pc->log, "CONNECT: %s" _ peer->addr_port_text.data); @@ -189,7 +189,10 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ p if (rc == -1) { err = ngx_socket_errno; - if (err != NGX_EINPROGRESS) { + + /* Winsock returns WSAEWOULDBLOCK */ + + if (err != NGX_EINPROGRESS && err != NGX_EAGAIN) { ngx_log_error(NGX_LOG_ERR, pc->log, err, "connect() failed"); if (ngx_close_socket(s) == -1) { @@ -221,7 +224,8 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ p /* * aio allows to post operation on non-connected socket - * at least in FreeBSD + * at least in FreeBSD. + * NT does not support it. * * TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT */ diff --git a/src/event/ngx_event_connectex.c b/src/event/ngx_event_connectex.c new file mode 100644 --- /dev/null +++ b/src/event/ngx_event_connectex.c @@ -0,0 +1,200 @@ + +#include +#include +#include + + +#define NGX_MAX_PENDING_CONN 10 + + +static CRITICAL_SECTION connect_lock; +static int nconnects; +static ngx_connection_t pending_connects[NGX_MAX_PENDING_CONN]; + +static HANDLE pending_connect_event; + +__declspec(thread) int nevents = 0; +__declspec(thread) WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS]; +__declspec(thread) ngx_connection_t *conn[WSA_MAXIMUM_WAIT_EVENTS]; + + + +int ngx_iocp_wait_connect(ngx_connection_t *c) +{ + for ( ;; ) { + EnterCriticalSection(&connect_lock); + + if (nconnects < NGX_MAX_PENDING_CONN) { + pending_connects[--nconnects] = c; + LeaveCriticalSection(&connect_lock); + + if (SetEvent(pending_connect_event) == 0) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "SetEvent() failed"); + return NGX_ERROR; + + break; + } + + LeaveCriticalSection(&connect_lock); + ngx_log_error(NGX_LOG_NOTICE, c->log, 0, + "max number of pending connect()s is %d", + NGX_MAX_PENDING_CONN); + msleep(100); + } + + if (!started) { + if (ngx_iocp_new_thread(1) == NGX_ERROR) { + return NGX_ERROR; + } + started = 1; + } + + return NGX_OK; +} + + +int ngx_iocp_new_thread(int main) +{ + u_int id; + + if (main) { + pending_connect_event = CreateEvent(NULL, 0, 1, NULL); + if (pending_connect_event == INVALID_HANDLE_VALUE) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "CreateThread() failed"); + return NGX_ERROR; + } + } + + if (CreateThread(NULL, 0, ngx_iocp_wait_events, main, 0, &id) + == INVALID_HANDLE_VALUE) + { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "CreateThread() failed"); + return NGX_ERROR; + } + + SetEvent(event) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "SetEvent() failed"); + return NGX_ERROR; + } + + return NGX_OK; +} + + +int ngx_iocp_new_connect() +{ + EnterCriticalSection(&connect_lock); + c = pending_connects[--nconnects]; + LeaveCriticalSection(&connect_lock); + + conn[nevents] = c; + + events[nevents] = WSACreateEvent(); + if (events[nevents] == INVALID_HANDLE_VALUE) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, + "WSACreateEvent() failed"); + return NGX_ERROR; + } + + if (WSAEventSelect(c->fd, events[nevents], FD_CONNECT) == -1) + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, + "WSAEventSelect() failed"); + return NGX_ERROR; + } + + nevents++; + + return NGX_OK; +} + + +void ngx_iocp_wait_events(int main) +{ + WSANETWORKEVENTS ne; + + nevents = 1; + events[0] = pending_connect_event; + conn[0] = NULL; + + for ( ;; ) { + offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS) ? 1: 0; + timeout = (nevents == 1 && !first) ? 60000: INFINITE; + + n = WSAWaitForMultipleEvents(nevents - offset, events[offset], + 0, timeout, 0); + if (n == WAIT_FAILED) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + "WSAWaitForMultipleEvents() failed"); + continue; + } + + if (n == WAIT_TIMEOUT) { + if (nevents == 1 && !main) { + ExitThread(0); + } + + ngx_log_error(NGX_LOG_ALERT, log, 0, + "WSAWaitForMultipleEvents() " + "returned unexpected WAIT_TIMEOUT"); + continue; + } + + n -= WSA_WAIT_EVENT_0; + + if (n == 0) { + + /* the first event is pending_connect_event */ + + if (nevents == WSA_MAXIMUM_WAIT_EVENTS) { + ngx_iocp_new_thread(0); + } else { + ngx_iocp_new_connect(); + } + + continue; + } + + if (WSAEnumNetworkEvents(c[n].fd, events[n], &ne) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + "WSAEnumNetworkEvents() failed"); + continue; + } + + if (ne.lNetworkEvents & FD_CONNECT) { + conn[n].write->ovlp.error = ne.iErrorCode[FD_CONNECT_BIT]; + + if (PostQueuedCompletionStatus(iocp, 0, NGX_IOCP_CONNECT, + &conn[n].write->ovlp) == 0) + { + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + "PostQueuedCompletionStatus() failed"); + continue; + } + + if (n < nevents) { + conn[n] = conn[nevents]; + events[n] = events[nevents]; + } + + nevents--; + continue; + } + + if (ne.lNetworkEvents & FD_ACCEPT) { + + /* CHECK ERROR ??? */ + + ngx_event_post_acceptex(conn[n].listening, 1); + continue; + } + + ngx_log_error(NGX_LOG_ALERT, c[n].log, 0, + "WSAWaitForMultipleEvents() " + "returned unexpected network event %lu", + ne.lNetworkEvents); + } +} diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -566,6 +566,8 @@ int ngx_event_pipe_copy_input_filter(ngx ngx_hunk_t *h; ngx_chain_t *cl; +ngx_log_debug(p->log, "COPY"); + if (hunk->pos == hunk->last) { return NGX_OK; } diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -202,7 +202,7 @@ static int ngx_http_index_test_dir(ngx_h ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); - if (ngx_file_type(r->path.data, &r->file.info) == -1) { + if (ngx_file_info(r->path.data, &r->file.info) == -1) { err = ngx_errno; @@ -212,14 +212,14 @@ ngx_log_debug(r->connection->log, "IS_DI } ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, - ngx_file_type_n " %s failed", r->path.data); + ngx_file_info_n " %s failed", r->path.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } r->path.data[r->path.len - 1] = '/'; - if (ngx_is_dir((&r->file.info))) { + if (ngx_is_dir(&r->file.info)) { return NGX_OK; } diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -95,10 +95,10 @@ ngx_log_debug(r->connection->log, "HTTP * so we need to check its type before the opening */ - if (ngx_file_type(r->file.name.data, &r->file.info) == NGX_FILE_ERROR) { + if (ngx_file_info(r->file.name.data, &r->file.info) == NGX_FILE_ERROR) { err = ngx_errno; ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - ngx_file_type_n " \"%s\" failed", r->file.name.data); + ngx_file_info_n " \"%s\" failed", r->file.name.data); if (err == NGX_ENOENT || err == NGX_ENOTDIR) { return NGX_HTTP_NOT_FOUND; @@ -111,7 +111,7 @@ ngx_log_debug(r->connection->log, "HTTP } } - if (ngx_is_dir(r->file.info)) { + if (ngx_is_dir(&r->file.info)) { ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data); if (!(r->headers_out.location = @@ -163,9 +163,9 @@ ngx_log_debug(r->connection->log, "HTTP ngx_log_debug(r->connection->log, "FILE: %d" _ r->file.fd); if (!r->file.info_valid) { - if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { + if (ngx_fd_info(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_stat_fd_n " \"%s\" failed", r->file.name.data); + ngx_fd_info_n " \"%s\" failed", r->file.name.data); if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, @@ -181,7 +181,7 @@ ngx_log_debug(r->connection->log, "FILE: r->file.info_valid = 1; } - if (ngx_is_dir((&r->file.info))) { + if (ngx_is_dir(&r->file.info)) { ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data); if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { @@ -210,7 +210,7 @@ ngx_log_debug(r->connection->log, "HTTP #if !(WIN32) /* the not regular files are probably Unix specific */ - if (!ngx_is_file((&r->file.info))) { + if (!ngx_is_file(&r->file.info)) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, "%s is not a regular file", r->file.name.data); @@ -272,9 +272,9 @@ static int ngx_http_static_handler(ngx_h } if (!r->file.info_valid) { - if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { + if (ngx_fd_info(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_stat_fd_n " %s failed", r->file.name.data); + ngx_fd_info_n " %s failed", r->file.name.data); if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, @@ -287,8 +287,8 @@ static int ngx_http_static_handler(ngx_h } r->headers_out.status = NGX_HTTP_OK; - r->headers_out.content_length_n = ngx_file_size((&r->file.info)); - r->headers_out.last_modified_time = ngx_file_mtime((&r->file.info)); + r->headers_out.content_length_n = ngx_file_size(&r->file.info); + r->headers_out.last_modified_time = ngx_file_mtime(&r->file.info); if (!(r->headers_out.content_type = ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) @@ -344,7 +344,7 @@ static int ngx_http_static_handler(ngx_h h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST; h->file_pos = 0; - h->file_last = ngx_file_size((&r->file.info)); + h->file_last = ngx_file_size(&r->file.info); h->file->fd = r->file.fd; h->file->log = r->connection->log; diff --git a/src/http/modules/proxy/ngx_http_proxy_cache.c b/src/http/modules/proxy/ngx_http_proxy_cache.c --- a/src/http/modules/proxy/ngx_http_proxy_cache.c +++ b/src/http/modules/proxy/ngx_http_proxy_cache.c @@ -270,11 +270,11 @@ void ngx_http_proxy_cache_busy_lock(ngx_ if (p->cache->ctx.file.fd != NGX_INVALID_FILE && !p->cache->ctx.file.info_valid) { - if (ngx_stat_fd(p->cache->ctx.file.fd, &p->cache->ctx.file.info) + if (ngx_fd_info(p->cache->ctx.file.fd, &p->cache->ctx.file.info) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, p->request->connection->log, ngx_errno, - ngx_stat_fd_n " \"%s\" failed", + ngx_fd_info_n " \"%s\" failed", p->cache->ctx.file.name.data); ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); return; @@ -322,7 +322,7 @@ static void ngx_http_proxy_cache_look_co *ctx = p->cache->ctx; rc = ngx_http_cache_open_file(p->request, ctx, - ngx_file_uniq((&p->cache->ctx.file.info))); + ngx_file_uniq(&p->cache->ctx.file.info)); if (rc == NGX_HTTP_CACHE_THE_SAME) { p->try_busy_lock = 1; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -480,7 +480,13 @@ static char *ngx_http_block(ngx_conf_t * ls->addr = offsetof(struct sockaddr_in, sin_addr); ls->addr_text_max_len = INET_ADDRSTRLEN; ls->backlog = -1; +#if 0 +#if 0 ls->nonblocking = 1; +#else + ls->nonblocking = 0; +#endif +#endif ls->handler = ngx_http_init_connection; diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c --- a/src/http/ngx_http_cache.c +++ b/src/http/ngx_http_cache.c @@ -5,8 +5,7 @@ #include -/* STUB */ -#if (WIN32) +#if (HAVE_OPENSSL_MD5) #define MD5Init MD5_Init #define MD5Update MD5_Update #define MD5Final MD5_Final @@ -71,14 +70,14 @@ int ngx_http_cache_open_file(ngx_http_re } if (uniq) { - if (ngx_stat_fd(ctx->file.fd, &ctx->file.info) == NGX_FILE_ERROR) { + if (ngx_fd_info(ctx->file.fd, &ctx->file.info) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_stat_fd_n " \"%s\" failed", ctx->file.name.data); + ngx_fd_info_n " \"%s\" failed", ctx->file.name.data); return NGX_ERROR; } - if (ngx_file_uniq((&ctx->file.info)) == uniq) { + if (ngx_file_uniq(&ctx->file.info) == uniq) { if (ngx_close_file(ctx->file.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, ngx_close_file_n " \"%s\" failed", @@ -140,12 +139,22 @@ int ngx_http_cache_update_file(ngx_http_ retry = 0; for ( ;; ) { - if (ngx_rename_file(temp_file, (&ctx->file.name), r->pool) == NGX_OK) { + if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) { return NGX_OK; } err = ngx_errno; +#if (WIN32) + if (err == NGX_EEXIST) { + if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool) + == NGX_ERROR) + { + return NGX_ERROR; + } + } +#endif + if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, ngx_rename_file_n "(\"%s\", \"%s\") failed", 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 @@ -19,10 +19,13 @@ typedef int ngx_err_t; #define NGX_ECONNRESET ECONNRESET #define NGX_ETIMEDOUT ETIMEDOUT #define NGX_ECANCELED ECANCELED +#define NGX_ENOMOREFILES 0 + #define ngx_errno errno #define ngx_socket_errno errno +#define ngx_set_errno(err) errno = err #define ngx_set_socket_errno(err) errno = err #if 0 diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -169,6 +169,20 @@ ssize_t ngx_write_chain_to_file(ngx_file } +int ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) +{ + dir->dir = opendir(name->data); + + if (dir->dir == NULL) { + return NGX_ERROR; + } + + dir->info_valid = 0; + + return NGX_OK; +} + + #if 0 ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset) diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -49,37 +49,59 @@ ssize_t ngx_write_chain_to_file(ngx_file off_t offset, ngx_pool_t *pool); -#define ngx_rename_file(from, to, pool) rename(from->data, to->data) +#define ngx_rename_file rename #define ngx_rename_file_n "rename" -#define ngx_open_dir opendir +#define ngx_file_info(file, sb) stat(file, sb) +#define ngx_file_info_n "stat()" + +#define ngx_fd_info(fd, sb) fstat(fd, sb) +#define ngx_fd_info_n "fstat()" + +#define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode)) +#define ngx_is_file(sb) (S_ISREG((sb)->st_mode)) +#define ngx_file_size(sb) (sb)->st_size +#define ngx_file_mtime(sb) (sb)->st_mtime +#define ngx_file_uniq(sb) (sb)->st_ino + + +#define NGX_DIR_MASK_LEN 0 + + +int ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir); #define ngx_open_dir_n "opendir()" -#define ngx_read_dir readdir +#define ngx_close_dir(d) closedir((d)->dir) +#define ngx_close_dir_n "closedir()" + + +#define ngx_read_dir(d) \ + (((d)->de = readdir((d)->dir)) ? NGX_OK : NGX_ERROR) #define ngx_read_dir_n "readdir()" -#define ngx_mkdir(name) mkdir(name, 0700) -#define ngx_mkdir_n "mkdir()" +#define ngx_create_dir(name) mkdir(name, 0700) +#define ngx_create_dir_n "mkdir()" #define ngx_delete_dir rmdir #define ngx_delete_dir_n "rmdir()" -#define ngx_file_type(file, sb) stat(file, sb) -#define ngx_file_type_n "stat()" - -#define ngx_stat_fd(fd, sb) fstat(fd, sb) -#define ngx_stat_fd_n "fstat()" - -#define ngx_is_dir(sb) (S_ISDIR(sb->st_mode)) -#define ngx_is_file(sb) (S_ISREG(sb->st_mode)) -#define ngx_file_size(sb) sb->st_size -#define ngx_file_mtime(sb) sb->st_mtime -#define ngx_file_uniq(sb) sb->st_ino +#define ngx_de_name(dir) (dir)->de->d_name +#ifdef __FreeBSD__ +#define ngx_de_namelen(dir) (dir)->de->d_namlen +#else +#define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name) +#endif +#define ngx_de_info(name, dir) stat(name, &(dir)->info) +#define ngx_de_info_n "stat()" +#define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode)) +#define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode)) +#define ngx_de_size(dir) (dir)->info.st_size +#define ngx_de_mtime(dir) (dir)->info.st_mtime #endif /* _NGX_FILES_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_types.h b/src/os/unix/ngx_types.h --- a/src/os/unix/ngx_types.h +++ b/src/os/unix/ngx_types.h @@ -9,8 +9,12 @@ typedef int ngx_fd_t; typedef struct stat ngx_file_info_t; typedef ino_t ngx_file_uniq_t; -typedef DIR ngx_dir_t; -typedef struct dirent ngx_dirent_t; +typedef struct { + DIR *dir; + struct dirent *de; + struct stat info; + unsigned info_valid; +} ngx_dir_t; #endif /* _NGX_TYPES_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_errno.c b/src/os/win32/ngx_errno.c --- a/src/os/win32/ngx_errno.c +++ b/src/os/win32/ngx_errno.c @@ -9,7 +9,7 @@ #include -ngx_str_t wsa_errors[] = { +static ngx_str_t wsa_errors[] = { ngx_string("Invalid argument"), /* 10022 */ ngx_null_string, /* 10023 */ ngx_null_string, /* 10024 */ @@ -23,7 +23,29 @@ ngx_str_t wsa_errors[] = { ngx_null_string, /* 10032 */ ngx_null_string, /* 10033 */ ngx_null_string, /* 10034 */ - ngx_string("Resource temporarily unavailable") /* 10035 */ + ngx_string("Resource temporarily unavailable"), /* 10035 */ + ngx_null_string, /* 10036 */ + ngx_null_string, /* 10037 */ + ngx_null_string, /* 10038 */ + ngx_null_string, /* 10039 */ + ngx_null_string, /* 10040 */ + ngx_null_string, /* 10041 */ + ngx_null_string, /* 10042 */ + ngx_null_string, /* 10043 */ + ngx_null_string, /* 10044 */ + ngx_null_string, /* 10045 */ + ngx_null_string, /* 10046 */ + ngx_null_string, /* 10047 */ + ngx_null_string, /* 10048 */ + ngx_null_string, /* 10049 */ + ngx_null_string, /* 10050 */ + ngx_null_string, /* 10051 */ + ngx_null_string, /* 10052 */ + ngx_null_string, /* 10053 */ + ngx_null_string, /* 10054 */ + ngx_null_string, /* 10055 */ + ngx_null_string, /* 10056 */ + ngx_string("Socket is not connected") /* 10057 */ }; @@ -45,7 +67,7 @@ int ngx_strerror_r(ngx_err_t err, char * if (format_error == ERROR_MR_MID_NOT_FOUND) { n = err - WSABASEERR - 22; - if (n >= 0 && n < 14) { + if (n >= 0 && n <= 35) { len = wsa_errors[n].len; if (len) { 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 @@ -9,6 +9,7 @@ typedef DWORD ngx_err_t; #define ngx_errno GetLastError() +#define ngx_set_errno(err) SetLastError(err) #define ngx_socket_errno WSAGetLastError() #define ngx_set_socket_errno(err) WSASetLastError(err) @@ -21,6 +22,10 @@ typedef DWORD ngx_e #define NGX_EADDRINUSE WSAEADDRINUSE #define NGX_ECONNRESET ECONNRESET #define NGX_ETIMEDOUT WSAETIMEDOUT +#define NGX_ENOMOREFILES ERROR_NO_MORE_FILES + +#define NGX_EALREADY WSAEALREADY +#define NGX_EINVAL WSAEINVAL int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size); 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 @@ -163,14 +163,16 @@ ssize_t ngx_write_chain_to_file(ngx_file } -int ngx_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool) +int ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool) { int rc, collision; u_int num; char *name; - ngx_err_t err; - name = ngx_palloc(pool, to->len + 1 + 10 + 1 + sizeof("DELETE")); + if (!(name = ngx_palloc(pool, to->len + 1 + 10 + 1 + sizeof("DELETE")))) { + return NGX_ERROR; + } + ngx_memcpy(name, to->data, to->len); collision = 0; @@ -184,11 +186,6 @@ int ngx_rename_file(ngx_str_t *from, ngx ".%010u.DELETE", num); if (MoveFile(to->data, name) == 0) { - err = ngx_errno; - if (err == NGX_ENOENT || err == NGX_ENOTDIR) { - return NGX_ERROR; - } - collision = 1; ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno, "MoveFile() failed"); @@ -196,18 +193,21 @@ int ngx_rename_file(ngx_str_t *from, ngx } while (collision); + if (MoveFile(from->data, to->data) == 0) { + rc = NGX_ERROR; + + } else { + rc = NGX_OK; + } + if (ngx_win32_version >= NGX_WIN_NT) { if (DeleteFile(name) == 0) { ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno, "DeleteFile() failed"); } - } - - if (MoveFile(from->data, to->data) == 0) { - rc = NGX_ERROR; } else { - rc = NGX_OK; + /* TODO: Win9X: update the open files table */ } if (rc == NGX_ERROR) { @@ -220,7 +220,9 @@ int ngx_rename_file(ngx_str_t *from, ngx } -int ngx_file_type(char *file, ngx_file_info_t *sb) +#if 0 + +int ngx_file_info(char *file, ngx_file_info_t *sb) { WIN32_FILE_ATTRIBUTE_DATA fa; @@ -240,13 +242,13 @@ int ngx_file_type(char *file, ngx_file_i return NGX_OK; } +#endif -#if 0 -/* Win95 */ +int ngx_file_info(char *file, ngx_file_info_t *sb) +{ + /* Win95 */ -int ngx_file_type(char *file, ngx_file_info_t *sb) -{ sb->dwFileAttributes = GetFileAttributes(file); if (sb->dwFileAttributes == INVALID_FILE_ATTRIBUTES) { @@ -256,7 +258,37 @@ int ngx_file_type(char *file, ngx_file_i return NGX_OK; } -#endif + +int ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) +{ + ngx_cpystrn(name->data + name->len, NGX_DIR_MASK, NGX_DIR_MASK_LEN + 1); + + dir->dir = FindFirstFile(name->data, &dir->fd); + + if (dir->dir == INVALID_HANDLE_VALUE) { + return NGX_ERROR; + } + + dir->info_valid = 1; + dir->ready = 1; + + return NGX_OK; +} + + +int ngx_read_dir(ngx_dir_t *dir) +{ + if (dir->ready) { + dir->ready = 0; + return NGX_OK; + } + + if (FindNextFile(dir->dir, &dir->fd) == 0) { + return NGX_ERROR; + } + + return NGX_OK; +} int ngx_file_append_mode(ngx_fd_t fd) 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 @@ -21,6 +21,8 @@ #define NGX_FILE_ERROR 0 +#define STDERR_FILENO (HANDLE) 2 + #define ngx_open_file(name, access, create) \ CreateFile(name, access, \ @@ -58,35 +60,87 @@ int ngx_file_append_mode(ngx_fd_t fd); #define ngx_close_file CloseHandle #define ngx_close_file_n "CloseHandle()" -int ngx_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool); -#define ngx_rename_file_n "MoveFile()" + +#define ngx_delete_file DeleteFile +#define ngx_delete_file_n "DeleteFile()" + -#define ngx_mkdir(name) CreateDirectory(name, NULL) -#define ngx_mkdir_n "CreateDirectory()" +#define ngx_rename_file MoveFile +#define ngx_rename_file_n "MoveFile()" +int ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool); -int ngx_file_type(char *filename, ngx_file_info_t *fi); -#define ngx_file_type_n "GetFileAttributesEx()" + +int ngx_file_info(char *filename, ngx_file_info_t *fi); +#define ngx_file_info_n "GetFileAttributesEx()" -#define ngx_stat_fd(fd, fi) GetFileInformationByHandle(fd, fi) -#define ngx_stat_fd_n "GetFileInformationByHandle" + +#define ngx_fd_info(fd, fi) GetFileInformationByHandle(fd, fi) +#define ngx_fd_info_n "GetFileInformationByHandle" + -#define ngx_is_dir(fi) (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) -#define ngx_is_file(fi) !(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define ngx_is_dir(fi) ((fi)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define ngx_is_file(fi) !((fi)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + -#define ngx_file_size(fi) \ - (((off_t) fi.nFileSizeHigh << 32) | fi.nFileSizeLow) +#define ngx_file_size(fi) \ + (((off_t) (fi)->nFileSizeHigh << 32) | (fi)->nFileSizeLow) -#define ngx_file_uniq(fi) (*(ngx_file_uniq_t *) &fi.nFileIndexHigh) +#define ngx_file_uniq(fi) (*(ngx_file_uniq_t *) &(fi)->nFileIndexHigh) /* 116444736000000000 is commented in src/os/win32/ngx_time.c */ -#define ngx_file_mtime(fi) \ - (time_t) (((((unsigned __int64) fi.ftLastWriteTime.dwHighDateTime << 32) \ - | fi.ftLastWriteTime.dwLowDateTime) \ +#define ngx_file_mtime(fi) \ + (time_t) (((((unsigned __int64) (fi)->ftLastWriteTime.dwHighDateTime << 32) \ + | (fi)->ftLastWriteTime.dwLowDateTime) \ - 116444736000000000) / 10000000) +#define NGX_DIR_MASK "/*" +#define NGX_DIR_MASK_LEN 2 + + +int ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir); +#define ngx_open_dir_n "FindFirstFile()" + + +int ngx_read_dir(ngx_dir_t *dir); +#define ngx_read_dir_n "FindNextFile()" + + +#define ngx_close_dir(d) FindClose((d)->dir) +#define ngx_close_dir_n "FindClose()" + + +#define ngx_create_dir(name) CreateDirectory(name, NULL) +#define ngx_create_dir_n "CreateDirectory()" + + +#define ngx_delete_dir RemoveDirectory +#define ngx_delete_dir_n "RemoveDirectory()" + + +#define ngx_de_name(dir) (dir)->fd.cFileName +#define ngx_de_namelen(dir) ngx_strlen((dir)->fd.cFileName) +#define ngx_de_info(name, dir) NGX_OK +#define ngx_de_info_n "dummy()" +#define ngx_de_is_dir(dir) \ + ((dir)->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define ngx_de_is_file(dir) \ + !((dir)->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define ngx_de_size(dir) \ + (((off_t) (dir)->fd.nFileSizeHigh << 32) | (dir)->fd.nFileSizeLow) + +/* 116444736000000000 is commented in src/os/win32/ngx_time.c */ + +#define ngx_de_mtime(dir) \ + (time_t) (((((unsigned __int64) \ + (dir)->fd.ftLastWriteTime.dwHighDateTime << 32) \ + | (dir)->fd.ftLastWriteTime.dwLowDateTime) \ + - 116444736000000000) / 10000000) + + + ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset); #define ngx_read_file_n "ReadFile()" @@ -96,8 +150,4 @@ ssize_t ngx_write_chain_to_file(ngx_file off_t offset, ngx_pool_t *pool); - -#define STDERR_FILENO (HANDLE) 2 - - #endif /* _NGX_FILES_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h --- a/src/os/win32/ngx_os.h +++ b/src/os/win32/ngx_os.h @@ -35,6 +35,7 @@ int ngx_os_init(ngx_log_t *log); ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size); ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, char *buf, size_t size); +ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain); ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in); ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in); diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h --- a/src/os/win32/ngx_socket.h +++ b/src/os/win32/ngx_socket.h @@ -13,8 +13,12 @@ typedef SOCKET ngx_socket_t; typedef int socklen_t; +#define ngx_socket(af, type, proto, flags) socket(af, type, proto) + +#if 0 #define ngx_socket(af, type, proto, flags) \ WSASocket(af, type, proto, NULL, 0, flags) +#endif #define ngx_socket_n "WSASocket()" @@ -36,7 +40,7 @@ extern LPFN_GETACCEPTEXSOCKADDRS getacc extern LPFN_TRANSMITFILE transmitfile; -ngx_inline int ngx_tcp_push(s) { +static ngx_inline int ngx_tcp_push(ngx_socket_t s) { return 0; } diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h --- a/src/os/win32/ngx_types.h +++ b/src/os/win32/ngx_types.h @@ -11,11 +11,11 @@ typedef BY_HANDLE_FILE_INFORMATION ngx_ typedef uint64_t ngx_file_uniq_t; typedef struct { - HANDLE dir; - WIN32_FIND_DATA de; + HANDLE dir; + WIN32_FIND_DATA fd; + unsigned info_valid; + unsigned ready; } ngx_dir_t; -typedef WIN32_FIND_DATA ngx_dirent_t; - #endif /* _NGX_TYPES_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -6,7 +6,18 @@ #define NGX_WIN_NT 200000 +#define STRICT +#define WIN32_LEAN_AND_MEAN +/* + * we need to include windows.h explicity before winsock2.h because + * warning 4201 is enabled in windows.h + */ +#include + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif #include #include @@ -15,6 +26,16 @@ #include #include +#ifdef _MSC_VER +#pragma warning(default:4201) + +/* unreferenced formal parameter */ +#pragma warning(disable:4100) + +/* STUB */ +#pragma warning(disable:4127) +#endif + #define ngx_inline __inline @@ -30,7 +51,7 @@ typedef u_int uintptr_t; typedef int ssize_t; typedef long time_t; -typedef unsigned __int64 off_t; +typedef __int64 off_t; #define OFF_FMT "%I64d" diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c --- a/src/os/win32/ngx_win32_init.c +++ b/src/os/win32/ngx_win32_init.c @@ -10,7 +10,7 @@ int ngx_inherited_nonblocking = 1; ngx_os_io_t ngx_os_io = { ngx_wsarecv, - NULL, + ngx_wsarecv_chain, NULL, ngx_wsasend_chain, 0 diff --git a/src/os/win32/ngx_wsarecv_chain.c b/src/os/win32/ngx_wsarecv_chain.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_wsarecv_chain.c @@ -0,0 +1,72 @@ + +#include +#include +#include + + +ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain) +{ + int rc; + char *prev; + u_int flags; + size_t bytes, size; + WSABUF *wsabuf; + ngx_err_t err; + ngx_array_t io; + ngx_event_t *rev; + + prev = NULL; + wsabuf = NULL; + flags = 0; + size = 0; + bytes = 0; + + ngx_init_array(io, c->pool, 10, sizeof(WSABUF), NGX_ERROR); + + /* coalesce the neighbouring hunks */ + + while (chain) { + if (prev == chain->hunk->last) { + wsabuf->len += chain->hunk->end - chain->hunk->last; + + } else { + ngx_test_null(wsabuf, ngx_push_array(&io), NGX_ERROR); + wsabuf->buf = chain->hunk->last; + wsabuf->len = chain->hunk->end - chain->hunk->last; + } + + size += chain->hunk->end - chain->hunk->last; + prev = chain->hunk->end; + chain = chain->next; + } + +ngx_log_debug(c->log, "WSARecv: %d:%d" _ io.nelts _ wsabuf->len); + + rc = WSARecv(c->fd, io.elts, io.nelts, &bytes, &flags, NULL, NULL); + + rev = c->read; + + if (rc == -1) { + rev->ready = 0; + err = ngx_socket_errno; + + if (err == WSAEWOULDBLOCK) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "WSARecv() EAGAIN"); + return NGX_AGAIN; + } + + rev->error = 1; + ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed"); + return NGX_ERROR; + } + + if (bytes < size) { + rev->ready = 0; + } + + if (bytes == 0) { + rev->eof = 1; + } + + return bytes; +}