changeset 185:d5f50cefc322

nginx-0.0.1-2003-11-14-19:52:04 import
author Igor Sysoev <igor@sysoev.ru>
date Fri, 14 Nov 2003 16:52:04 +0000
parents 1bf718ce0dde
children c1f3a3c7c5db
files src/core/nginx.c src/core/ngx_conf_file.c src/core/ngx_file.h src/core/ngx_garbage_collector.c src/http/modules/ngx_http_index_handler.c src/http/modules/ngx_http_static_handler.c src/http/modules/proxy/ngx_http_proxy_cache.c src/http/ngx_http_cache.c src/os/unix/ngx_files.h src/os/unix/ngx_freebsd_config.h src/os/unix/ngx_types.h src/os/win32/ngx_files.c src/os/win32/ngx_files.h src/os/win32/ngx_types.h
diffstat 14 files changed, 351 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -5,6 +5,10 @@
 #include <nginx.h>
 
 
+/* 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++;
--- 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;
             }
 
--- 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;
new file mode 100644
--- /dev/null
+++ b/src/core/ngx_garbage_collector.c
@@ -0,0 +1,256 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+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;
+}
--- 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;
     }
 
--- 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;
--- 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;
--- 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",
--- 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_ */
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -10,6 +10,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/uio.h>
 #include <sys/ioctl.h>
@@ -19,6 +20,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>        /* TCP_NOPUSH */
+#include <dirent.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <osreldate.h>
--- a/src/os/unix/ngx_types.h
+++ b/src/os/unix/ngx_types.h
@@ -4,14 +4,13 @@
 
 #include <ngx_config.h>
 
-#include <sys/types.h>
-#include <sys/stat.h>
-
 
-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_ */
--- 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) {
--- 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"
--- 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_ */