Mercurial > hg > nginx-vendor-0-7
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 } |