# HG changeset patch # User Igor Sysoev # Date 1068828724 0 # Node ID d5f50cefc32255564942561ce62f2dada0b9017f # Parent 1bf718ce0dde46a1438cca3611d2f2bfca6cb313 nginx-0.0.1-2003-11-14-19:52:04 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -5,6 +5,10 @@ #include +/* STUB */ +void stub_init(ngx_log_t *log); + + static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle, ngx_log_t *log); static int ngx_open_listening_sockets(ngx_cycle_t *cycle, ngx_log_t *log); static void ngx_clean_old_cycles(ngx_event_t *ev); @@ -93,6 +97,8 @@ int main(int argc, char *const *argv) return 1; } + stub_init(log); + ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = ngx_max_module++; 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 @@ -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_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -18,6 +18,7 @@ struct ngx_file_s { unsigned info_valid:1; }; +#define NGX_MAX_PATH_LEVEL 3 typedef struct { ngx_str_t name; diff --git a/src/core/ngx_garbage_collector.c b/src/core/ngx_garbage_collector.c new file mode 100644 --- /dev/null +++ b/src/core/ngx_garbage_collector.c @@ -0,0 +1,256 @@ + +#include +#include + + +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); + +struct ngx_gc_s { + ngx_path_t *path; + u_int deleted; + off_t freed; + ngx_gc_handler_pt handler; + ngx_log_t *log; +}; + + +static int ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, int level); + + + +#if 0 + +{ + ngx_test_null(cycle->timer_events, + ngx_alloc(sizeof(ngx_event_t) * TIMERS, cycle->log), + NGX_ERROR); + + ngx_event_timer_init(cycle); +} + + +void garbage_collector() +{ + ngx_msec_t timer; + struct timeval tv; + ngx_epoch_msec_t delta; + + for ( ;; ) { + timer = ngx_event_find_timer(); + + ngx_gettimeofday(&tv); + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; + + msleep(timer); + + ngx_gettimeofday(&tv); + + ngx_cached_time = tv.tv_sec; + ngx_time_update(); + + delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; + + ngx_event_expire_timers((ngx_msec_t) delta); + } +} + +#endif + + +void stub_init(ngx_log_t *log) +{ + ngx_gc_t *ctx; + ngx_path_t path; + + if (!(ctx = ngx_alloc(sizeof(ngx_gc_t), log))) { + return; + } + + path.name.len = 4; + path.name.data = "temp"; + path.len = 5; + path.level[0] = 1; + path.level[1] = 2; + path.level[2] = 0; + + ctx->path = &path; + ctx->log = log; + + ngx_collect_garbage(ctx, &path.name, 0); +} + + +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; + + fname.len = 0; + +ngx_log_debug(ctx->log, "dir %s" _ dname->data); + + 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); + return NGX_ERROR; + } + + for ( ;; ) { + de = ngx_read_dir(dir); + + if (de == NULL) { + if (fname.len) { + ngx_free(fname.data); + } + break; + } + +ngx_log_debug(ctx->log, "file %s" _ de->d_name); + +#ifdef __FreeBSD__ + nlen = de->d_namlen; +#else + nlen = ngx_strlen(de->d_name); +#endif + + if (nlen == 1 && de->d_name[0] == '.') { + continue; + } + + if (nlen == 2 && de->d_name[0] == '.' && de->d_name[1] == '.') { + continue; + } + + if (dname->len + 1 + nlen > fname.len) { + if (fname.len) { + ngx_free(fname.data); + } + + fname.len = dname->len + 1 + nlen; + + if (!(fname.data = ngx_alloc(fname.len + 1, ctx->log))) { + return NGX_ABORT; + } + } + + last = ngx_cpymem(fname.data, dname->data, dname->len); + *last++ = '/'; + ngx_memcpy(last, de->d_name, nlen + 1); + +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 (ngx_is_dir((&fi))) { + +ngx_log_debug(ctx->log, "enter %s" _ fname.data); + + if (level == -1 + /* 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]) + { + if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) { + return NGX_ABORT; + } + + ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, + "delete old hierachy directory \"%s\"", + fname.data); + + if (ngx_delete_dir(fname.data) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_delete_dir_n " \"%s\" failed", + fname.data); + } else { + ctx->deleted++; + ctx->freed += ngx_file_size((&fi)); + } + + continue; + } + + if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) { + return NGX_ABORT; + } + + } else if (ngx_is_file((&fi))) { + + if (level == -1 + || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0)) + { + if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", + fname.data); + } else { + ctx->deleted++; + ctx->freed += ngx_file_size((&fi)); + } + + continue; + } + + if (ctx->handler(ctx, &fname, &fi) == NGX_ABORT) { + return NGX_ABORT; + } + + } else { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + "\"%s\" has unknown file type, deleting", fname.data); + + if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", fname.data); + } else { + ctx->deleted++; + ctx->freed += ngx_file_size((&fi)); + } + } + } + + return NGX_OK; +} + + +int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, + ngx_file_info_t *fi) +{ + /* + * we use mtime only and do not use atime because: + * on NTFS access time has a resolution of 1 hour, + * on NT FAT access time has a resolution of 1 day, + * Unices have mount option "noatime" + */ + + if (ngx_cached_time - ngx_file_mtime(fi) < 3600) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, + "delete stale temporary \"%s\"", name->data); + + if (ngx_delete_file(name->data) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", name->data); + return NGX_ERROR; + } + + ctx->deleted++; + ctx->freed += ngx_file_size(fi); + 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 @@ -219,7 +219,7 @@ ngx_log_debug(r->connection->log, "IS_DI 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 @@ -90,13 +90,12 @@ ngx_log_debug(r->connection->log, "HTTP if (ngx_win32_version < NGX_WIN_NT) { /* - * There is no way to open a file or a directory in Win9X with - * one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag. - * So we need to check its type before the opening. + * there is no way to open a file or a directory in Win9X with + * one syscall because Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag + * so we need to check its type before the opening */ - r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data); - if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { + if (ngx_file_type(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); @@ -182,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) { @@ -211,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); @@ -288,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))) @@ -345,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 @@ -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_cache.c b/src/http/ngx_http_cache.c --- a/src/http/ngx_http_cache.c +++ b/src/http/ngx_http_cache.c @@ -78,7 +78,7 @@ int ngx_http_cache_open_file(ngx_http_re 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", 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 @@ -30,6 +30,10 @@ #define ngx_close_file_n "close()" +#define ngx_delete_file unlink +#define ngx_delete_file_n "unlink()" + + #define ngx_open_tempfile(name, persistent) \ open(name, O_CREAT|O_EXCL|O_RDWR, 0600) #define ngx_open_tempfile_n "open()" @@ -49,21 +53,33 @@ ssize_t ngx_write_chain_to_file(ngx_file #define ngx_rename_file_n "rename" +#define ngx_open_dir opendir +#define ngx_open_dir_n "opendir()" + + +#define ngx_read_dir readdir +#define ngx_read_dir_n "readdir()" + + #define ngx_mkdir(name) mkdir(name, 0700) #define ngx_mkdir_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_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 #endif /* _NGX_FILES_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include /* TCP_NOPUSH */ +#include #include #include #include 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 @@ -4,14 +4,13 @@ #include -#include -#include - -typedef int ngx_fd_t; -typedef struct stat ngx_file_info_t; -typedef ino_t ngx_file_uniq_t; +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; #endif /* _NGX_TYPES_H_INCLUDED_ */ 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 @@ -220,6 +220,45 @@ int ngx_rename_file(ngx_str_t *from, ngx } +int ngx_file_type(char *file, ngx_file_info_t *sb) +{ + WIN32_FILE_ATTRIBUTE_DATA fa; + + /* NT4 and Win98 */ + + if (GetFileAttributesEx(file, GetFileExInfoStandard, &fa) == 0) { + return NGX_ERROR; + } + + sb->dwFileAttributes = fa.dwFileAttributes; + sb->ftCreationTime = fa.ftCreationTime; + sb->ftLastAccessTime = fa.ftLastAccessTime; + sb->ftLastWriteTime = fa.ftLastWriteTime; + sb->nFileSizeHigh = fa.nFileSizeHigh; + sb->nFileSizeLow = fa.nFileSizeLow; + + return NGX_OK; +} + + +#if 0 + +/* Win95 */ + +int ngx_file_type(char *file, ngx_file_info_t *sb) +{ + sb->dwFileAttributes = GetFileAttributes(file); + + if (sb->dwFileAttributes == INVALID_FILE_ATTRIBUTES) { + return NGX_ERROR; + } + + return NGX_OK; +} + +#endif + + int ngx_file_append_mode(ngx_fd_t fd) { if (SetFilePointer(fd, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) { 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 @@ -65,7 +65,7 @@ int ngx_rename_file(ngx_str_t *from, ngx #define ngx_mkdir_n "CreateDirectory()" int ngx_file_type(char *filename, ngx_file_info_t *fi); -#define ngx_file_type_n "GetFileAttributes" +#define ngx_file_type_n "GetFileAttributesEx()" #define ngx_stat_fd(fd, fi) GetFileInformationByHandle(fd, fi) #define ngx_stat_fd_n "GetFileInformationByHandle" 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 @@ -10,5 +10,12 @@ typedef HANDLE ngx_ typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t; typedef uint64_t ngx_file_uniq_t; +typedef struct { + HANDLE dir; + WIN32_FIND_DATA de; +} ngx_dir_t; + +typedef WIN32_FIND_DATA ngx_dirent_t; + #endif /* _NGX_TYPES_H_INCLUDED_ */