0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #include <ngx_config.h>
|
|
8 #include <ngx_core.h>
|
|
9
|
|
10
|
110
|
11 ssize_t
|
|
12 ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
|
0
|
13 {
|
110
|
14 ssize_t n;
|
0
|
15
|
|
16 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
|
10
|
17 "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
|
0
|
18
|
18
|
19 #if (NGX_HAVE_PREAD)
|
0
|
20
|
|
21 n = pread(file->fd, buf, size, offset);
|
|
22
|
|
23 if (n == -1) {
|
|
24 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
|
|
25 "pread() failed, file \"%s\"", file->name.data);
|
|
26 return NGX_ERROR;
|
|
27 }
|
|
28
|
|
29 #else
|
|
30
|
|
31 if (file->sys_offset != offset) {
|
|
32 if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
|
33 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
|
|
34 return NGX_ERROR;
|
|
35 }
|
|
36
|
|
37 file->sys_offset = offset;
|
|
38 }
|
|
39
|
|
40 n = read(file->fd, buf, size);
|
|
41
|
|
42 if (n == -1) {
|
|
43 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed");
|
|
44 return NGX_ERROR;
|
|
45 }
|
|
46
|
|
47 file->sys_offset += n;
|
|
48
|
|
49 #endif
|
|
50
|
|
51 file->offset += n;
|
|
52
|
|
53 return n;
|
|
54 }
|
|
55
|
|
56
|
110
|
57 ssize_t
|
|
58 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
|
0
|
59 {
|
110
|
60 ssize_t n;
|
0
|
61
|
10
|
62 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
|
|
63 "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
|
|
64
|
18
|
65 #if (NGX_HAVE_PWRITE)
|
0
|
66
|
|
67 n = pwrite(file->fd, buf, size, offset);
|
|
68
|
|
69 if (n == -1) {
|
|
70 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed");
|
|
71 return NGX_ERROR;
|
|
72 }
|
|
73
|
|
74 if ((size_t) n != size) {
|
|
75 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
10
|
76 "pwrite() has written only %z of %uz", n, size);
|
0
|
77 return NGX_ERROR;
|
|
78 }
|
|
79
|
|
80 #else
|
|
81
|
|
82 if (file->sys_offset != offset) {
|
|
83 if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
|
84 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
|
|
85 return NGX_ERROR;
|
|
86 }
|
|
87
|
|
88 file->sys_offset = offset;
|
|
89 }
|
|
90
|
|
91 n = write(file->fd, buf, size);
|
|
92
|
|
93 if (n == -1) {
|
|
94 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "write() failed");
|
|
95 return NGX_ERROR;
|
|
96 }
|
|
97
|
|
98 if ((size_t) n != size) {
|
|
99 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
10
|
100 "write() has written only %z of %uz", n, size);
|
0
|
101 return NGX_ERROR;
|
|
102 }
|
|
103
|
|
104 file->sys_offset += n;
|
|
105
|
|
106 #endif
|
|
107
|
|
108 file->offset += n;
|
|
109
|
|
110 return n;
|
|
111 }
|
|
112
|
|
113
|
110
|
114 ngx_fd_t
|
276
|
115 ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
|
0
|
116 {
|
|
117 ngx_fd_t fd;
|
|
118
|
276
|
119 fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
|
|
120 access ? access : 0600);
|
0
|
121
|
|
122 if (fd != -1 && !persistent) {
|
|
123 unlink((const char *) name);
|
|
124 }
|
|
125
|
|
126 return fd;
|
|
127 }
|
|
128
|
|
129
|
10
|
130 #define NGX_IOVS 8
|
|
131
|
110
|
132 ssize_t
|
|
133 ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
|
|
134 ngx_pool_t *pool)
|
0
|
135 {
|
|
136 u_char *prev;
|
|
137 size_t size;
|
|
138 ssize_t n;
|
10
|
139 ngx_array_t vec;
|
|
140 struct iovec *iov, iovs[NGX_IOVS];
|
0
|
141
|
10
|
142 /* use pwrite() if there is the only buf in a chain */
|
0
|
143
|
|
144 if (cl->next == NULL) {
|
|
145 return ngx_write_file(file, cl->buf->pos,
|
|
146 (size_t) (cl->buf->last - cl->buf->pos),
|
|
147 offset);
|
|
148 }
|
|
149
|
10
|
150 vec.elts = iovs;
|
|
151 vec.size = sizeof(struct iovec);
|
126
|
152 vec.nalloc = NGX_IOVS;
|
10
|
153 vec.pool = pool;
|
0
|
154
|
10
|
155 do {
|
|
156 prev = NULL;
|
|
157 iov = NULL;
|
|
158 size = 0;
|
0
|
159
|
10
|
160 vec.nelts = 0;
|
|
161
|
|
162 /* create the iovec and coalesce the neighbouring bufs */
|
0
|
163
|
10
|
164 while (cl && vec.nelts < IOV_MAX) {
|
|
165 if (prev == cl->buf->pos) {
|
|
166 iov->iov_len += cl->buf->last - cl->buf->pos;
|
0
|
167
|
10
|
168 } else {
|
50
|
169 iov = ngx_array_push(&vec);
|
|
170 if (iov == NULL) {
|
10
|
171 return NGX_ERROR;
|
|
172 }
|
|
173
|
|
174 iov->iov_base = (void *) cl->buf->pos;
|
|
175 iov->iov_len = cl->buf->last - cl->buf->pos;
|
|
176 }
|
|
177
|
|
178 size += cl->buf->last - cl->buf->pos;
|
|
179 prev = cl->buf->last;
|
|
180 cl = cl->next;
|
0
|
181 }
|
|
182
|
10
|
183 /* use pwrite() if there is the only iovec buffer */
|
0
|
184
|
10
|
185 if (vec.nelts == 1) {
|
|
186 iov = vec.elts;
|
|
187 return ngx_write_file(file, (u_char *) iov[0].iov_base,
|
|
188 iov[0].iov_len, offset);
|
|
189 }
|
0
|
190
|
10
|
191 if (file->sys_offset != offset) {
|
|
192 if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
|
193 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
|
|
194 "lseek() failed");
|
|
195 return NGX_ERROR;
|
|
196 }
|
0
|
197
|
10
|
198 file->sys_offset = offset;
|
|
199 }
|
|
200
|
|
201 n = writev(file->fd, vec.elts, vec.nelts);
|
|
202
|
|
203 if (n == -1) {
|
|
204 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
|
|
205 "writev() failed");
|
0
|
206 return NGX_ERROR;
|
|
207 }
|
|
208
|
10
|
209 if ((size_t) n != size) {
|
|
210 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
|
211 "writev() has written only %z of %uz", n, size);
|
|
212 return NGX_ERROR;
|
|
213 }
|
0
|
214
|
10
|
215 file->sys_offset += n;
|
|
216 file->offset += n;
|
0
|
217
|
10
|
218 } while (cl);
|
0
|
219
|
|
220 return n;
|
|
221 }
|
|
222
|
|
223
|
110
|
224 ngx_int_t
|
230
|
225 ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
|
|
226 {
|
|
227 struct timeval tv[2];
|
|
228
|
|
229 tv[0].tv_sec = s;
|
|
230 tv[0].tv_usec = 0;
|
|
231 tv[1].tv_sec = s;
|
|
232 tv[1].tv_usec = 0;
|
|
233
|
|
234 if (utimes((char *) name, tv) != -1) {
|
|
235 return NGX_OK;
|
|
236 }
|
|
237
|
|
238 return NGX_ERROR;
|
|
239 }
|
|
240
|
|
241
|
|
242 ngx_int_t
|
110
|
243 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
|
0
|
244 {
|
|
245 dir->dir = opendir((const char *) name->data);
|
|
246
|
|
247 if (dir->dir == NULL) {
|
|
248 return NGX_ERROR;
|
|
249 }
|
|
250
|
6
|
251 dir->valid_info = 0;
|
0
|
252
|
|
253 return NGX_OK;
|
|
254 }
|
110
|
255
|
|
256
|
238
|
257 ngx_int_t
|
|
258 ngx_open_glob(ngx_glob_t *gl)
|
|
259 {
|
240
|
260 if (glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob) == 0) {
|
238
|
261 return NGX_OK;
|
|
262 }
|
|
263
|
|
264 return NGX_ERROR;
|
|
265 }
|
|
266
|
|
267
|
|
268 ngx_int_t
|
|
269 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
|
|
270 {
|
240
|
271 if (gl->n < (size_t) gl->pglob.gl_pathc) {
|
238
|
272
|
|
273 name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
|
|
274 name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
|
|
275 gl->n++;
|
|
276
|
|
277 return NGX_OK;
|
|
278 }
|
|
279
|
|
280 return NGX_DONE;
|
|
281 }
|
|
282
|
|
283
|
|
284 void
|
|
285 ngx_close_glob(ngx_glob_t *gl)
|
|
286 {
|
|
287 globfree(&gl->pglob);
|
|
288 }
|
|
289
|
|
290
|
160
|
291 ngx_err_t
|
|
292 ngx_trylock_fd(ngx_fd_t fd)
|
110
|
293 {
|
|
294 struct flock fl;
|
|
295
|
160
|
296 fl.l_start = 0;
|
|
297 fl.l_len = 0;
|
|
298 fl.l_pid = 0;
|
|
299 fl.l_type = F_WRLCK;
|
110
|
300 fl.l_whence = SEEK_SET;
|
160
|
301
|
|
302 if (fcntl(fd, F_SETLK, &fl) == -1) {
|
|
303 return ngx_errno;
|
|
304 }
|
|
305
|
|
306 return 0;
|
|
307 }
|
|
308
|
|
309
|
|
310 ngx_err_t
|
|
311 ngx_lock_fd(ngx_fd_t fd)
|
|
312 {
|
|
313 struct flock fl;
|
|
314
|
|
315 fl.l_start = 0;
|
110
|
316 fl.l_len = 0;
|
|
317 fl.l_pid = 0;
|
|
318 fl.l_type = F_WRLCK;
|
160
|
319 fl.l_whence = SEEK_SET;
|
110
|
320
|
160
|
321 if (fcntl(fd, F_SETLKW, &fl) == -1) {
|
|
322 return ngx_errno;
|
110
|
323 }
|
|
324
|
160
|
325 return 0;
|
110
|
326 }
|
|
327
|
|
328
|
160
|
329 ngx_err_t
|
|
330 ngx_unlock_fd(ngx_fd_t fd)
|
110
|
331 {
|
|
332 struct flock fl;
|
|
333
|
160
|
334 fl.l_start = 0;
|
110
|
335 fl.l_len = 0;
|
|
336 fl.l_pid = 0;
|
|
337 fl.l_type = F_UNLCK;
|
160
|
338 fl.l_whence = SEEK_SET;
|
110
|
339
|
160
|
340 if (fcntl(fd, F_SETLK, &fl) == -1) {
|
|
341 return ngx_errno;
|
110
|
342 }
|
|
343
|
160
|
344 return 0;
|
110
|
345 }
|