comparison src/core/ngx_file.c @ 0:f0b350454894 NGINX_0_1_0

nginx 0.1.0 *) The first public version.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Oct 2004 00:00:00 +0400
parents
children 46833bd150cb
comparison
equal deleted inserted replaced
-1:000000000000 0:f0b350454894
1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9
10
11 static ngx_uint_t ngx_temp_number;
12 static ngx_uint_t ngx_random;
13
14
15 int ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
16 {
17 int rc;
18
19 if (tf->file.fd == NGX_INVALID_FILE) {
20 rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool,
21 tf->persistent);
22
23 if (rc == NGX_ERROR || rc == NGX_AGAIN) {
24 return rc;
25 }
26
27 if (!tf->persistent && tf->warn) {
28 ngx_log_error(NGX_LOG_WARN, tf->file.log, 0, tf->warn);
29 }
30 }
31
32 return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool);
33 }
34
35
36 int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
37 ngx_pool_t *pool, int persistent)
38 {
39 int num;
40 ngx_err_t err;
41
42 file->name.len = path->name.len + 1 + path->len + 10;
43
44 ngx_test_null(file->name.data, ngx_palloc(pool, file->name.len + 1),
45 NGX_ERROR);
46
47 #if 0
48 for (i = 0; i < file->name.len; i++) {
49 file->name.data[i] = 'X';
50 }
51 #endif
52
53 ngx_memcpy(file->name.data, path->name.data, path->name.len);
54
55 num = ngx_next_temp_number(0);
56
57 for ( ;; ) {
58 ngx_snprintf((char *)
59 (file->name.data + path->name.len + 1 + path->len),
60 11, "%010u", num);
61
62 ngx_create_hashed_filename(file, path);
63
64 #if 1
65 file->fd = ngx_open_tempfile(file->name.data, persistent);
66 #else
67 file->fd = ngx_open_tempfile(file->name.data, 1);
68 #endif
69
70 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
71 "temp fd:%d", file->fd);
72
73 if (file->fd != NGX_INVALID_FILE) {
74 return NGX_OK;
75 }
76
77 err = ngx_errno;
78
79 if (err == NGX_EEXIST) {
80 num = ngx_next_temp_number(1);
81 continue;
82 }
83
84 if ((path->level[0] == 0)
85 || (err != NGX_ENOENT
86 #if (WIN32)
87 && err != NGX_ENOTDIR
88 #endif
89 )) {
90 ngx_log_error(NGX_LOG_CRIT, file->log, err,
91 ngx_open_tempfile_n " \"%s\" failed",
92 file->name.data);
93 return NGX_ERROR;
94 }
95
96 if (ngx_create_path(file, path) == NGX_ERROR) {
97 return NGX_ERROR;
98 }
99 }
100 }
101
102
103 void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path)
104 {
105 int i, name, pos;
106 size_t level;
107
108 name = file->name.len;
109 pos = path->name.len + 1;
110
111 file->name.data[path->name.len + path->len] = '/';
112
113 for (i = 0; i < 3; i++) {
114 level = path->level[i];
115
116 if (level == 0) {
117 break;
118 }
119
120 name -= level;
121 file->name.data[pos - 1] = '/';
122 ngx_memcpy(&file->name.data[pos], &file->name.data[name], level);
123 pos += level + 1;
124 }
125
126 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
127 "hashed path: %s", file->name.data);
128 }
129
130
131 int ngx_create_path(ngx_file_t *file, ngx_path_t *path)
132 {
133 int i, pos;
134 ngx_err_t err;
135
136 pos = path->name.len;
137
138 for (i = 0; i < 3; i++) {
139 if (path->level[i] == 0) {
140 break;
141 }
142
143 pos += path->level[i] + 1;
144
145 file->name.data[pos] = '\0';
146
147 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
148 "temp file: \"%s\"", file->name.data);
149
150 if (ngx_create_dir(file->name.data) == NGX_FILE_ERROR) {
151 err = ngx_errno;
152 if (err != NGX_EEXIST) {
153 ngx_log_error(NGX_LOG_CRIT, file->log, err,
154 ngx_create_dir_n " \"%s\" failed",
155 file->name.data);
156 return NGX_ERROR;
157 }
158 }
159
160 file->name.data[pos] = '/';
161 }
162
163 return NGX_OK;
164 }
165
166
167 void ngx_init_temp_number()
168 {
169 ngx_random = 0;
170
171 ngx_temp_number = ngx_random;
172
173 while (ngx_random < 10000) {
174 ngx_random = 123456;
175 }
176 }
177
178
179 ngx_uint_t ngx_next_temp_number(ngx_uint_t collision)
180 {
181 if (collision) {
182 ngx_temp_number += ngx_random;
183 }
184
185 return ngx_temp_number++;
186 }
187
188
189 char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
190 {
191 char *p = conf;
192
193 ngx_int_t level;
194 ngx_uint_t i, n;
195 ngx_str_t *value;
196 ngx_path_t *path, **pp;
197
198 pp = (ngx_path_t **) (p + cmd->offset);
199
200 if (*pp) {
201 return "is duplicate";
202 }
203
204 /* TODO: check duplicate in cf->cycle->pathes */
205
206 ngx_test_null(path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),
207 NGX_CONF_ERROR);
208
209 *pp = path;
210
211 ngx_test_null(pp, ngx_push_array(&cf->cycle->pathes), NGX_CONF_ERROR);
212 *pp = path;
213
214 value = (ngx_str_t *) cf->args->elts;
215
216 path->name = value[1];
217
218 path->len = 0;
219
220 for (i = 0, n = 2; n < cf->args->nelts; i++, n++) {
221 level = ngx_atoi(value[n].data, value[n].len);
222 if (level == NGX_ERROR || level == 0) {
223 return "invalid value";
224 }
225
226 path->level[i] = level;
227 path->len += level + 1;
228 }
229
230 while (i < 3) {
231 path->level[i++] = 0;
232 }
233
234 path->gc_handler = (ngx_gc_handler_pt) cmd->post;
235
236 return NGX_CONF_OK;
237 }