~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/os/unix/ngx_files.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 
 10 
 11 ssize_t
 12 ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
 13 {
 14     ssize_t  n;
 15 
 16     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
 17                    "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
 18 
 19 #if (NGX_HAVE_PREAD)
 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() \"%s\" failed", 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,
 34                           "lseek() \"%s\" failed", file->name.data);
 35             return NGX_ERROR;
 36         }
 37 
 38         file->sys_offset = offset;
 39     }
 40 
 41     n = read(file->fd, buf, size);
 42 
 43     if (n == -1) {
 44         ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 45                       "read() \"%s\" failed", file->name.data);
 46         return NGX_ERROR;
 47     }
 48 
 49     file->sys_offset += n;
 50 
 51 #endif
 52 
 53     file->offset += n;
 54 
 55     return n;
 56 }
 57 
 58 
 59 ssize_t
 60 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
 61 {
 62     ssize_t  n, written;
 63 
 64     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
 65                    "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
 66 
 67     written = 0;
 68 
 69 #if (NGX_HAVE_PWRITE)
 70 
 71     for ( ;; ) {
 72         n = pwrite(file->fd, buf, size, offset);
 73 
 74         if (n == -1) {
 75             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 76                           "pwrite() \"%s\" failed", file->name.data);
 77             return NGX_ERROR;
 78         }
 79 
 80         file->offset += n;
 81         written += n;
 82 
 83         if ((size_t) n == size) {
 84             return written;
 85         }
 86 
 87         offset += n;
 88         size -= n;
 89     }
 90 
 91 #else
 92 
 93     if (file->sys_offset != offset) {
 94         if (lseek(file->fd, offset, SEEK_SET) == -1) {
 95             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 96                           "lseek() \"%s\" failed", file->name.data);
 97             return NGX_ERROR;
 98         }
 99 
100         file->sys_offset = offset;
101     }
102 
103     for ( ;; ) {
104         n = write(file->fd, buf, size);
105 
106         if (n == -1) {
107             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
108                           "write() \"%s\" failed", file->name.data);
109             return NGX_ERROR;
110         }
111 
112         file->offset += n;
113         written += n;
114 
115         if ((size_t) n == size) {
116             return written;
117         }
118 
119         size -= n;
120     }
121 #endif
122 }
123 
124 
125 ngx_fd_t
126 ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
127 {
128     ngx_fd_t  fd;
129 
130     fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
131               access ? access : 0600);
132 
133     if (fd != -1 && !persistent) {
134         unlink((const char *) name);
135     }
136 
137     return fd;
138 }
139 
140 
141 #define NGX_IOVS  8
142 
143 ssize_t
144 ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
145     ngx_pool_t *pool)
146 {
147     u_char        *prev;
148     size_t         size;
149     ssize_t        n;
150     ngx_array_t    vec;
151     struct iovec  *iov, iovs[NGX_IOVS];
152 
153     /* use pwrite() if there is the only buf in a chain */
154 
155     if (cl->next == NULL) {
156         return ngx_write_file(file, cl->buf->pos,
157                               (size_t) (cl->buf->last - cl->buf->pos),
158                               offset);
159     }
160 
161     vec.elts = iovs;
162     vec.size = sizeof(struct iovec);
163     vec.nalloc = NGX_IOVS;
164     vec.pool = pool;
165 
166     do {
167         prev = NULL;
168         iov = NULL;
169         size = 0;
170 
171         vec.nelts = 0;
172 
173         /* create the iovec and coalesce the neighbouring bufs */
174 
175         while (cl && vec.nelts < IOV_MAX) {
176             if (prev == cl->buf->pos) {
177                 iov->iov_len += cl->buf->last - cl->buf->pos;
178 
179             } else {
180                 iov = ngx_array_push(&vec);
181                 if (iov == NULL) {
182                     return NGX_ERROR;
183                 }
184 
185                 iov->iov_base = (void *) cl->buf->pos;
186                 iov->iov_len = cl->buf->last - cl->buf->pos;
187             }
188 
189             size += cl->buf->last - cl->buf->pos;
190             prev = cl->buf->last;
191             cl = cl->next;
192         }
193 
194         /* use pwrite() if there is the only iovec buffer */
195 
196         if (vec.nelts == 1) {
197             iov = vec.elts;
198             return ngx_write_file(file, (u_char *) iov[0].iov_base,
199                                   iov[0].iov_len, offset);
200         }
201 
202         if (file->sys_offset != offset) {
203             if (lseek(file->fd, offset, SEEK_SET) == -1) {
204                 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
205                               "lseek() \"%s\" failed", file->name.data);
206                 return NGX_ERROR;
207             }
208 
209             file->sys_offset = offset;
210         }
211 
212         n = writev(file->fd, vec.elts, vec.nelts);
213 
214         if (n == -1) {
215             ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
216                           "writev() \"%s\" failed", file->name.data);
217             return NGX_ERROR;
218         }
219 
220         if ((size_t) n != size) {
221             ngx_log_error(NGX_LOG_CRIT, file->log, 0,
222                           "writev() \"%s\" has written only %z of %uz",
223                           file->name.data, n, size);
224             return NGX_ERROR;
225         }
226 
227         file->sys_offset += n;
228         file->offset += n;
229 
230     } while (cl);
231 
232     return n;
233 }
234 
235 
236 ngx_int_t
237 ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
238 {
239     struct timeval  tv[2];
240 
241     tv[0].tv_sec = s;
242     tv[0].tv_usec = 0;
243     tv[1].tv_sec = s;
244     tv[1].tv_usec = 0;
245 
246     if (utimes((char *) name, tv) != -1) {
247         return NGX_OK;
248     }
249 
250     return NGX_ERROR;
251 }
252 
253 
254 ngx_int_t
255 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
256 {
257     dir->dir = opendir((const char *) name->data);
258 
259     if (dir->dir == NULL) {
260         return NGX_ERROR;
261     }
262 
263     dir->valid_info = 0;
264 
265     return NGX_OK;
266 }
267 
268 
269 ngx_int_t
270 ngx_read_dir(ngx_dir_t *dir)
271 {
272     dir->de = readdir(dir->dir);
273 
274     if (dir->de) {
275 #if (NGX_HAVE_D_TYPE)
276         dir->type = dir->de->d_type;
277 #else
278         dir->type = 0;
279 #endif
280         return NGX_OK;
281     }
282 
283     return NGX_ERROR;
284 }
285 
286 
287 ngx_int_t
288 ngx_open_glob(ngx_glob_t *gl)
289 {
290     int  n;
291 
292     n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
293 
294     if (n == 0) {
295         return NGX_OK;
296     }
297 
298 #ifdef GLOB_NOMATCH
299 
300     if (n == GLOB_NOMATCH && gl->test) {
301         return NGX_OK;
302     }
303 
304 #endif
305 
306     return NGX_ERROR;
307 }
308 
309 
310 ngx_int_t
311 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
312 {
313     size_t  count;
314 
315 #ifdef GLOB_NOMATCH
316     count = (size_t) gl->pglob.gl_pathc;
317 #else
318     count = (size_t) gl->pglob.gl_matchc;
319 #endif
320 
321     if (gl->n < count) {
322 
323         name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
324         name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
325         gl->n++;
326 
327         return NGX_OK;
328     }
329 
330     return NGX_DONE;
331 }
332 
333 
334 void
335 ngx_close_glob(ngx_glob_t *gl)
336 {
337     globfree(&gl->pglob);
338 }
339 
340 
341 ngx_err_t
342 ngx_trylock_fd(ngx_fd_t fd)
343 {
344     struct flock  fl;
345 
346     fl.l_start = 0;
347     fl.l_len = 0;
348     fl.l_pid = 0;
349     fl.l_type = F_WRLCK;
350     fl.l_whence = SEEK_SET;
351 
352     if (fcntl(fd, F_SETLK, &fl) == -1) {
353         return ngx_errno;
354     }
355 
356     return 0;
357 }
358 
359 
360 ngx_err_t
361 ngx_lock_fd(ngx_fd_t fd)
362 {
363     struct flock  fl;
364 
365     fl.l_start = 0;
366     fl.l_len = 0;
367     fl.l_pid = 0;
368     fl.l_type = F_WRLCK;
369     fl.l_whence = SEEK_SET;
370 
371     if (fcntl(fd, F_SETLKW, &fl) == -1) {
372         return ngx_errno;
373     }
374 
375     return 0;
376 }
377 
378 
379 ngx_err_t
380 ngx_unlock_fd(ngx_fd_t fd)
381 {
382     struct flock  fl;
383 
384     fl.l_start = 0;
385     fl.l_len = 0;
386     fl.l_pid = 0;
387     fl.l_type = F_UNLCK;
388     fl.l_whence = SEEK_SET;
389 
390     if (fcntl(fd, F_SETLK, &fl) == -1) {
391         return  ngx_errno;
392     }
393 
394     return 0;
395 }
396 
397 
398 #if (NGX_HAVE_O_DIRECT)
399 
400 ngx_int_t
401 ngx_directio_on(ngx_fd_t fd)
402 {
403     int  flags;
404 
405     flags = fcntl(fd, F_GETFL);
406 
407     if (flags == -1) {
408         return NGX_FILE_ERROR;
409     }
410 
411     return fcntl(fd, F_SETFL, flags | O_DIRECT);
412 }
413 
414 
415 ngx_int_t
416 ngx_directio_off(ngx_fd_t fd)
417 {
418     int  flags;
419 
420     flags = fcntl(fd, F_GETFL);
421 
422     if (flags == -1) {
423         return NGX_FILE_ERROR;
424     }
425 
426     return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
427 }
428 
429 #endif
430 
431 
432 #if (NGX_HAVE_STATFS)
433 
434 size_t
435 ngx_fs_bsize(u_char *name)
436 {
437     struct statfs  fs;
438 
439     if (statfs((char *) name, &fs) == -1) {
440         return 512;
441     }
442 
443     if ((fs.f_bsize % 512) != 0) {
444         return 512;
445     }
446 
447     return (size_t) fs.f_bsize;
448 }
449 
450 #elif (NGX_HAVE_STATVFS)
451 
452 size_t
453 ngx_fs_bsize(u_char *name)
454 {
455     struct statvfs  fs;
456 
457     if (statvfs((char *) name, &fs) == -1) {
458         return 512;
459     }
460 
461     if ((fs.f_frsize % 512) != 0) {
462         return 512;
463     }
464 
465     return (size_t) fs.f_frsize;
466 }
467 
468 #else
469 
470 size_t
471 ngx_fs_bsize(u_char *name)
472 {
473     return 512;
474 }
475 
476 #endif
477 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.