diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/ngx_file.c | 33 | ||||
| -rw-r--r-- | src/core/ngx_open_file_cache.c | 2 | ||||
| -rw-r--r-- | src/core/ngx_output_chain.c | 4 | ||||
| -rw-r--r-- | src/http/ngx_http_request.c | 6 | ||||
| -rw-r--r-- | src/os/unix/ngx_files.c | 80 | ||||
| -rw-r--r-- | src/os/win32/ngx_files.c | 220 | ||||
| -rw-r--r-- | src/os/win32/ngx_files.h | 2 |
7 files changed, 173 insertions, 174 deletions
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c index 45bb4ca4f..6844849ad 100644 --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -183,7 +183,15 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access) u_char *p, ch; ngx_err_t err; - for (p = dir + 1; *p; p++) { + err = 0; + +#if (NGX_WIN32) + p = dir + 3; +#else + p = dir + 1; +#endif + + for ( /* void */ ; *p; p++) { ch = *p; if (ch != '/') { @@ -194,7 +202,14 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access) if (ngx_create_dir(dir, access) == NGX_FILE_ERROR) { err = ngx_errno; - if (err != NGX_EEXIST) { + + switch (err) { + case NGX_EEXIST: + err = 0; + case NGX_EACCES: + break; + + default: return err; } } @@ -202,7 +217,7 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access) *p = '/'; } - return 0; + return err; } @@ -576,16 +591,10 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext) #if (NGX_WIN32) if (err == NGX_EEXIST) { - if (ngx_win32_rename_file(src, to, ext->log) == NGX_OK) { + err = ngx_win32_rename_file(src, to, ext->log); - if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) { - return NGX_OK; - } - - err = ngx_errno; - - } else { - err = 0; + if (err == 0) { + return NGX_OK; } } diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c index aa87fd22c..5f6e0b263 100644 --- a/src/core/ngx_open_file_cache.c +++ b/src/core/ngx_open_file_cache.c @@ -525,7 +525,7 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log) of->fd = fd; if (of->directio <= ngx_file_size(&fi)) { - if (ngx_directio_on(fd) == -1) { + if (ngx_directio_on(fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, ngx_directio_on_n " \"%s\" failed", name); diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c index bee7952ca..808addd85 100644 --- a/src/core/ngx_output_chain.c +++ b/src/core/ngx_output_chain.c @@ -510,7 +510,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx) #if (NGX_HAVE_ALIGNED_DIRECTIO) if (ctx->unaligned) { - if (ngx_directio_off(src->file->fd) == -1) { + if (ngx_directio_off(src->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno, ngx_directio_off_n " \"%s\" failed", src->file->name.data); @@ -528,7 +528,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx) err = ngx_errno; - if (ngx_directio_on(src->file->fd) == -1) { + if (ngx_directio_on(src->file->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno, ngx_directio_on_n " \"%s\" failed", src->file->name.data); diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 3ad4a4973..c239b9d34 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -784,9 +784,11 @@ ngx_http_process_request_line(ngx_event_t *rev) p = r->uri.data + r->uri.len - 1; - if (*p == '.') { + if (*p == '.' || *p == ' ') { - while (--p > r->uri.data && *p == '.') { /* void */ } + while (--p > r->uri.data && (*p == '.' || *p == ' ')) { + /* void */ + } r->uri.len = p + 1 - r->uri.data; diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c index 10436a918..618d4e214 100644 --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -22,7 +22,7 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) if (n == -1) { ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, - "pread() failed, file \"%s\"", file->name.data); + "pread() \"%s\" failed", file->name.data); return NGX_ERROR; } @@ -30,7 +30,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) if (file->sys_offset != offset) { if (lseek(file->fd, offset, SEEK_SET) == -1) { - ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed"); + ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, + "lseek() \"%s\" failed", file->name.data); return NGX_ERROR; } @@ -40,7 +41,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) n = read(file->fd, buf, size); if (n == -1) { - ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed"); + ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, + "read() \"%s\" failed", file->name.data); return NGX_ERROR; } @@ -57,57 +59,66 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { - ssize_t n; + ssize_t n, written; ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, "write: %d, %p, %uz, %O", file->fd, buf, size, offset); + written = 0; + #if (NGX_HAVE_PWRITE) - n = pwrite(file->fd, buf, size, offset); + for ( ;; ) { + n = pwrite(file->fd, buf, size, offset); - if (n == -1) { - ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed"); - return NGX_ERROR; - } + if (n == -1) { + ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, + "pwrite() \"%s\" failed", file->name.data); + return NGX_ERROR; + } - if ((size_t) n != size) { - ngx_log_error(NGX_LOG_CRIT, file->log, 0, - "pwrite() has written only %z of %uz", n, size); - return NGX_ERROR; + file->offset += n; + written += n; + + if ((size_t) n == size) { + return written; + } + + offset += n; + size -= n; } #else if (file->sys_offset != offset) { if (lseek(file->fd, offset, SEEK_SET) == -1) { - ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed"); + ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, + "lseek() \"%s\" failed", file->name.data); return NGX_ERROR; } file->sys_offset = offset; } - n = write(file->fd, buf, size); + for ( ;; ) { + n = write(file->fd, buf, size); - if (n == -1) { - ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "write() failed"); - return NGX_ERROR; - } + if (n == -1) { + ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, + "write() \"%s\" failed", file->name.data); + return NGX_ERROR; + } - if ((size_t) n != size) { - ngx_log_error(NGX_LOG_CRIT, file->log, 0, - "write() has written only %z of %uz", n, size); - return NGX_ERROR; - } + file->offset += n; + written += n; - file->sys_offset += n; + if ((size_t) n == size) { + return written; + } + size -= n; + } #endif - - file->offset += n; - - return n; } @@ -191,7 +202,7 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset, if (file->sys_offset != offset) { if (lseek(file->fd, offset, SEEK_SET) == -1) { ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, - "lseek() failed"); + "lseek() \"%s\" failed", file->name.data); return NGX_ERROR; } @@ -202,13 +213,14 @@ ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset, if (n == -1) { ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, - "writev() failed"); + "writev() \"%s\" failed", file->name.data); return NGX_ERROR; } if ((size_t) n != size) { ngx_log_error(NGX_LOG_CRIT, file->log, 0, - "writev() has written only %z of %uz", n, size); + "writev() \"%s\" has written only %z of %uz", + file->name.data, n, size); return NGX_ERROR; } @@ -393,7 +405,7 @@ ngx_directio_on(ngx_fd_t fd) flags = fcntl(fd, F_GETFL); if (flags == -1) { - return -1; + return NGX_FILE_ERROR; } return fcntl(fd, F_SETFL, flags | O_DIRECT); @@ -408,7 +420,7 @@ ngx_directio_off(ngx_fd_t fd) flags = fcntl(fd, F_GETFL); if (flags == -1) { - return -1; + return NGX_FILE_ERROR; } return fcntl(fd, F_SETFL, flags & ~O_DIRECT); diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c index 94bdc8840..24f744399 100644 --- a/src/os/win32/ngx_files.c +++ b/src/os/win32/ngx_files.c @@ -10,7 +10,7 @@ #define NGX_UTF16_BUFLEN 256 -static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len); +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 */ @@ -18,24 +18,60 @@ static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len); 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]; + size_t len; + u_long n; + u_short *u, *lu; + ngx_fd_t fd; + ngx_err_t err; + u_short utf16[NGX_UTF16_BUFLEN]; - u = ngx_utf8_to_utf16(utf16, name, NGX_UTF16_BUFLEN); + len = NGX_UTF16_BUFLEN; + u = ngx_utf8_to_utf16(utf16, name, &len); if (u == NULL) { return INVALID_HANDLE_VALUE; } + fd = INVALID_HANDLE_VALUE; + lu = NULL; + + if (create == NGX_FILE_OPEN) { + + lu = malloc(len * 2); + if (lu == NULL) { + goto failed; + } + + n = GetLongPathNameW(u, lu, len); + + if (n == 0) { + goto failed; + } + + if (n != len - 1 || ngx_memcmp(u, lu, n) != 0) { + ngx_set_errno(NGX_ENOENT); + goto failed; + } + } + fd = CreateFileW(u, mode, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL); +failed: + + err = ngx_errno; + + if (lu) { + ngx_free(lu); + } + if (u != utf16) { ngx_free(u); } + ngx_set_errno(err); + return fd; } @@ -43,56 +79,17 @@ ngx_open_file(u_char *name, u_long mode, u_long create, u_long access) ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { - long high_offset; u_long n; ngx_err_t err; OVERLAPPED ovlp, *povlp; - if (ngx_win32_version < NGX_WIN_NT) { - - /* - * under Win9X the overlapped pointer must be NULL - * so we have to use SetFilePointer() to set the offset - */ - - if (file->offset != offset) { - - /* - * the maximum file size on the FAT16 is 2G, but on the FAT32 - * the size is 4G so we have to use the high_offset - * because a single offset is signed value - */ - - high_offset = (long) (offset >> 32); - - if (SetFilePointer(file->fd, (long) offset, &high_offset, - FILE_BEGIN) == INVALID_SET_FILE_POINTER) - { - /* - * INVALID_SET_FILE_POINTER is 0xffffffff and it can be valid - * value for large file so we need also to check GetLastError() - */ - - err = ngx_errno; - if (err != NO_ERROR) { - ngx_log_error(NGX_LOG_ERR, file->log, err, - "SeekFilePointer() failed"); - return NGX_ERROR; - } - } - } - - povlp = NULL; - - } else { - ovlp.Internal = 0; - ovlp.InternalHigh = 0; - ovlp.Offset = (u_long) offset; - ovlp.OffsetHigh = (u_long) (offset >> 32); - ovlp.hEvent = NULL; + ovlp.Internal = 0; + ovlp.InternalHigh = 0; + ovlp.Offset = (u_long) offset; + ovlp.OffsetHigh = (u_long) (offset >> 32); + ovlp.hEvent = NULL; - povlp = &ovlp; - } + povlp = &ovlp; if (ReadFile(file->fd, buf, size, &n, povlp) == 0) { err = ngx_errno; @@ -101,7 +98,8 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) return 0; } - ngx_log_error(NGX_LOG_ERR, file->log, err, "ReadFile() failed"); + ngx_log_error(NGX_LOG_ERR, file->log, err, + "ReadFile() \"%s\" failed", file->name.data); return NGX_ERROR; } @@ -114,58 +112,27 @@ ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) { - long high_offset; u_long n; - ngx_err_t err; OVERLAPPED ovlp, *povlp; - if (ngx_win32_version < NGX_WIN_NT) { - - /* - * under Win9X the overlapped pointer must be NULL - * so we have to use SetFilePointer() to set the offset - */ - - if (file->offset != offset) { - - /* - * the maximum file size on the FAT16 is 2G, but on the FAT32 - * the size is 4G so we have to use high_offset - * because a single offset is signed value - */ - - high_offset = (long) (offset >> 32); - if (SetFilePointer(file->fd, (long) offset, &high_offset, - FILE_BEGIN) == INVALID_SET_FILE_POINTER) - { - /* - * INVALID_SET_FILE_POINTER is 0xffffffff and it can be valid - * value for large file so we need also to check GetLastError() - */ - - err = ngx_errno; - if (err != NO_ERROR) { - ngx_log_error(NGX_LOG_ERR, file->log, err, - "SeekFilePointer() failed"); - return NGX_ERROR; - } - } - } + ovlp.Internal = 0; + ovlp.InternalHigh = 0; + ovlp.Offset = (u_long) offset; + ovlp.OffsetHigh = (u_long) (offset >> 32); + ovlp.hEvent = NULL; - povlp = NULL; - - } else { - ovlp.Internal = 0; - ovlp.InternalHigh = 0; - ovlp.Offset = (u_long) offset; - ovlp.OffsetHigh = (u_long) (offset >> 32); - ovlp.hEvent = NULL; + povlp = &ovlp; - povlp = &ovlp; + if (WriteFile(file->fd, buf, size, &n, povlp) == 0) { + ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, + "WriteFile() \"%s\" failed", file->name.data); + return NGX_ERROR; } - if (WriteFile(file->fd, buf, size, &n, povlp) == 0) { - ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "WriteFile() failed"); + if (n != size) { + ngx_log_error(NGX_LOG_CRIT, file->log, 0, + "WriteFile() \"%s\" has written only %ul of %uz", + file->name.data, n, size); return NGX_ERROR; } @@ -253,17 +220,17 @@ ngx_write_console(ngx_fd_t fd, void *buf, size_t size) } -ngx_int_t +ngx_err_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log) { u_char *name; - ngx_int_t rc; + ngx_err_t err; ngx_uint_t collision; ngx_atomic_uint_t num; name = ngx_alloc(to->len + 1 + 10 + 1 + sizeof("DELETE"), log); if (name == NULL) { - return NGX_ERROR; + return NGX_ENOMEM; } ngx_memcpy(name, to->data, to->len); @@ -288,10 +255,10 @@ ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log) } if (MoveFile((const char *) from->data, (const char *) to->data) == 0) { - rc = NGX_ERROR; + err = ngx_errno; } else { - rc = NGX_OK; + err = 0; } if (DeleteFile((const char *) name) == 0) { @@ -299,31 +266,40 @@ ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log) "DeleteFile() \"%s\" failed", name); } - if (rc == NGX_ERROR) { - ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, - "MoveFile() \"%s\" to \"%s\" failed", - from->data, to->data); - } - /* mutex_unlock() */ ngx_free(name); - return rc; + return err; } ngx_int_t ngx_file_info(u_char *file, ngx_file_info_t *sb) { - WIN32_FILE_ATTRIBUTE_DATA fa; + size_t len; + long rc; + u_short *u; + ngx_err_t err; + WIN32_FILE_ATTRIBUTE_DATA fa; + u_short utf16[NGX_UTF16_BUFLEN]; + + len = NGX_UTF16_BUFLEN; - /* NT4 and Win98 */ + u = ngx_utf8_to_utf16(utf16, file, &len); - if (GetFileAttributesEx((char *) file, GetFileExInfoStandard, &fa) == 0) { + if (u == NULL) { return NGX_FILE_ERROR; } + rc = GetFileAttributesExW(u, GetFileExInfoStandard, &fa); + + if (u != utf16) { + err = ngx_errno; + ngx_free(u); + ngx_set_errno(err); + } + sb->dwFileAttributes = fa.dwFileAttributes; sb->ftCreationTime = fa.ftCreationTime; sb->ftLastAccessTime = fa.ftLastAccessTime; @@ -331,7 +307,7 @@ ngx_file_info(u_char *file, ngx_file_info_t *sb) sb->nFileSizeHigh = fa.nFileSizeHigh; sb->nFileSizeLow = fa.nFileSizeLow; - return ~NGX_FILE_ERROR; + return rc; } @@ -533,14 +509,14 @@ ngx_de_link_info(u_char *name, ngx_dir_t *dir) ngx_int_t ngx_directio_on(ngx_fd_t fd) { - return 0; + return ~NGX_FILE_ERROR; } ngx_int_t ngx_directio_off(ngx_fd_t fd) { - return 0; + return ~NGX_FILE_ERROR; } @@ -564,7 +540,7 @@ ngx_fs_bsize(u_char *name) static u_short * -ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len) +ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len) { u_char *p; u_short *u, *last; @@ -572,18 +548,18 @@ ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len) p = utf8; u = utf16; - last = utf16 + len; + last = utf16 + *len; while (u < last) { if (*p < 0x80) { - *u = (u_short) *p; + *u++ = (u_short) *p; if (*p == 0) { + *len = u - utf16; return utf16; } - u++; p++; continue; @@ -607,21 +583,21 @@ ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len) return NULL; } - ngx_memcpy(u, utf16, len * 2); + ngx_memcpy(u, utf16, *len * 2); utf16 = u; - u += len; + u += *len; for ( ;; ) { if (*p < 0x80) { - *u = (u_short) *p; + *u++ = (u_short) *p; if (*p == 0) { + *len = u - utf16; return utf16; } - u++; p++; continue; diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h index 757c44a6f..c11379f4f 100644 --- a/src/os/win32/ngx_files.h +++ b/src/os/win32/ngx_files.h @@ -111,7 +111,7 @@ ssize_t ngx_write_console(ngx_fd_t fd, void *buf, size_t size); #define ngx_rename_file(o, n) MoveFile((const char *) o, (const char *) n) #define ngx_rename_file_n "MoveFile()" -ngx_int_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log); +ngx_err_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log); |
