~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/os/unix/ngx_files.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
8
9
#include <ngx_core.h>
9
10
 
10
11
 
 
12
#if (NGX_HAVE_FILE_AIO)
 
13
 
 
14
ngx_uint_t  ngx_file_aio = 1;
 
15
 
 
16
#endif
 
17
 
 
18
 
11
19
ssize_t
12
20
ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
13
21
{
22
30
 
23
31
    if (n == -1) {
24
32
        ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
25
 
                      "pread() failed, file \"%s\"", file->name.data);
 
33
                      "pread() \"%s\" failed", file->name.data);
26
34
        return NGX_ERROR;
27
35
    }
28
36
 
30
38
 
31
39
    if (file->sys_offset != offset) {
32
40
        if (lseek(file->fd, offset, SEEK_SET) == -1) {
33
 
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
 
41
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 
42
                          "lseek() \"%s\" failed", file->name.data);
34
43
            return NGX_ERROR;
35
44
        }
36
45
 
40
49
    n = read(file->fd, buf, size);
41
50
 
42
51
    if (n == -1) {
43
 
        ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed");
 
52
        ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 
53
                      "read() \"%s\" failed", file->name.data);
44
54
        return NGX_ERROR;
45
55
    }
46
56
 
57
67
ssize_t
58
68
ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
59
69
{
60
 
    ssize_t  n;
 
70
    ssize_t  n, written;
61
71
 
62
72
    ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
63
73
                   "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
64
74
 
 
75
    written = 0;
 
76
 
65
77
#if (NGX_HAVE_PWRITE)
66
78
 
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,
76
 
                      "pwrite() has written only %z of %uz", n, size);
77
 
        return NGX_ERROR;
 
79
    for ( ;; ) {
 
80
        n = pwrite(file->fd, buf + written, size, offset);
 
81
 
 
82
        if (n == -1) {
 
83
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 
84
                          "pwrite() \"%s\" failed", file->name.data);
 
85
            return NGX_ERROR;
 
86
        }
 
87
 
 
88
        file->offset += n;
 
89
        written += n;
 
90
 
 
91
        if ((size_t) n == size) {
 
92
            return written;
 
93
        }
 
94
 
 
95
        offset += n;
 
96
        size -= n;
78
97
    }
79
98
 
80
99
#else
81
100
 
82
101
    if (file->sys_offset != offset) {
83
102
        if (lseek(file->fd, offset, SEEK_SET) == -1) {
84
 
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
 
103
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 
104
                          "lseek() \"%s\" failed", file->name.data);
85
105
            return NGX_ERROR;
86
106
        }
87
107
 
88
108
        file->sys_offset = offset;
89
109
    }
90
110
 
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,
100
 
                      "write() has written only %z of %uz", n, size);
101
 
        return NGX_ERROR;
102
 
    }
103
 
 
104
 
    file->sys_offset += n;
105
 
 
 
111
    for ( ;; ) {
 
112
        n = write(file->fd, buf + written, size);
 
113
 
 
114
        if (n == -1) {
 
115
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 
116
                          "write() \"%s\" failed", file->name.data);
 
117
            return NGX_ERROR;
 
118
        }
 
119
 
 
120
        file->offset += n;
 
121
        written += n;
 
122
 
 
123
        if ((size_t) n == size) {
 
124
            return written;
 
125
        }
 
126
 
 
127
        size -= n;
 
128
    }
106
129
#endif
107
 
 
108
 
    file->offset += n;
109
 
 
110
 
    return n;
111
130
}
112
131
 
113
132
 
120
139
              access ? access : 0600);
121
140
 
122
141
    if (fd != -1 && !persistent) {
123
 
        unlink((const char *) name);
 
142
        (void) unlink((const char *) name);
124
143
    }
125
144
 
126
145
    return fd;
135
154
{
136
155
    u_char        *prev;
137
156
    size_t         size;
138
 
    ssize_t        n;
 
157
    ssize_t        total, n;
139
158
    ngx_array_t    vec;
140
159
    struct iovec  *iov, iovs[NGX_IOVS];
141
160
 
147
166
                              offset);
148
167
    }
149
168
 
 
169
    total = 0;
 
170
 
150
171
    vec.elts = iovs;
151
172
    vec.size = sizeof(struct iovec);
152
173
    vec.nalloc = NGX_IOVS;
184
205
 
185
206
        if (vec.nelts == 1) {
186
207
            iov = vec.elts;
187
 
            return ngx_write_file(file, (u_char *) iov[0].iov_base,
188
 
                                  iov[0].iov_len, offset);
 
208
 
 
209
            n = ngx_write_file(file, (u_char *) iov[0].iov_base,
 
210
                               iov[0].iov_len, offset);
 
211
 
 
212
            if (n == NGX_ERROR) {
 
213
                return n;
 
214
            }
 
215
 
 
216
            return total + n;
189
217
        }
190
218
 
191
219
        if (file->sys_offset != offset) {
192
220
            if (lseek(file->fd, offset, SEEK_SET) == -1) {
193
221
                ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
194
 
                              "lseek() failed");
 
222
                              "lseek() \"%s\" failed", file->name.data);
195
223
                return NGX_ERROR;
196
224
            }
197
225
 
202
230
 
203
231
        if (n == -1) {
204
232
            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
205
 
                          "writev() failed");
 
233
                          "writev() \"%s\" failed", file->name.data);
206
234
            return NGX_ERROR;
207
235
        }
208
236
 
209
237
        if ((size_t) n != size) {
210
238
            ngx_log_error(NGX_LOG_CRIT, file->log, 0,
211
 
                          "writev() has written only %z of %uz", n, size);
 
239
                          "writev() \"%s\" has written only %z of %uz",
 
240
                          file->name.data, n, size);
212
241
            return NGX_ERROR;
213
242
        }
214
243
 
 
244
        ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
 
245
                       "writev: %d, %z", file->fd, n);
 
246
 
215
247
        file->sys_offset += n;
216
248
        file->offset += n;
 
249
        offset += n;
 
250
        total += n;
217
251
 
218
252
    } while (cl);
219
253
 
220
 
    return n;
 
254
    return total;
221
255
}
222
256
 
223
257
 
226
260
{
227
261
    struct timeval  tv[2];
228
262
 
229
 
    tv[0].tv_sec = s;
 
263
    tv[0].tv_sec = ngx_time();
230
264
    tv[0].tv_usec = 0;
231
265
    tv[1].tv_sec = s;
232
266
    tv[1].tv_usec = 0;
240
274
 
241
275
 
242
276
ngx_int_t
 
277
ngx_create_file_mapping(ngx_file_mapping_t *fm)
 
278
{
 
279
    fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
 
280
                           NGX_FILE_DEFAULT_ACCESS);
 
281
    if (fm->fd == NGX_INVALID_FILE) {
 
282
        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
 
283
                      ngx_open_file_n " \"%s\" failed", fm->name);
 
284
        return NGX_ERROR;
 
285
    }
 
286
 
 
287
    if (ftruncate(fm->fd, fm->size) == -1) {
 
288
        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
 
289
                      "ftruncate() \"%s\" failed", fm->name);
 
290
        goto failed;
 
291
    }
 
292
 
 
293
    fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
 
294
                    fm->fd, 0);
 
295
    if (fm->addr != MAP_FAILED) {
 
296
        return NGX_OK;
 
297
    }
 
298
 
 
299
    ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
 
300
                  "mmap(%uz) \"%s\" failed", fm->size, fm->name);
 
301
 
 
302
failed:
 
303
 
 
304
    if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
 
305
        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
 
306
                      ngx_close_file_n " \"%s\" failed", fm->name);
 
307
    }
 
308
 
 
309
    return NGX_ERROR;
 
310
}
 
311
 
 
312
 
 
313
void
 
314
ngx_close_file_mapping(ngx_file_mapping_t *fm)
 
315
{
 
316
    if (munmap(fm->addr, fm->size) == -1) {
 
317
        ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
 
318
                      "munmap(%uz) \"%s\" failed", fm->size, fm->name);
 
319
    }
 
320
 
 
321
    if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
 
322
        ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
 
323
                      ngx_close_file_n " \"%s\" failed", fm->name);
 
324
    }
 
325
}
 
326
 
 
327
 
 
328
ngx_int_t
243
329
ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
244
330
{
245
331
    dir->dir = opendir((const char *) name->data);
255
341
 
256
342
 
257
343
ngx_int_t
 
344
ngx_read_dir(ngx_dir_t *dir)
 
345
{
 
346
    dir->de = readdir(dir->dir);
 
347
 
 
348
    if (dir->de) {
 
349
#if (NGX_HAVE_D_TYPE)
 
350
        dir->type = dir->de->d_type;
 
351
#else
 
352
        dir->type = 0;
 
353
#endif
 
354
        return NGX_OK;
 
355
    }
 
356
 
 
357
    return NGX_ERROR;
 
358
}
 
359
 
 
360
 
 
361
ngx_int_t
258
362
ngx_open_glob(ngx_glob_t *gl)
259
363
{
260
364
    int  n;
261
365
 
262
 
    n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
 
366
    n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
263
367
 
264
368
    if (n == 0) {
265
369
        return NGX_OK;
266
370
    }
267
371
 
 
372
#ifdef GLOB_NOMATCH
 
373
 
268
374
    if (n == GLOB_NOMATCH && gl->test) {
269
375
        return NGX_OK;
270
376
    }
271
377
 
 
378
#endif
 
379
 
272
380
    return NGX_ERROR;
273
381
}
274
382
 
276
384
ngx_int_t
277
385
ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
278
386
{
279
 
    if (gl->n < (size_t) gl->pglob.gl_pathc) {
 
387
    size_t  count;
 
388
 
 
389
#ifdef GLOB_NOMATCH
 
390
    count = (size_t) gl->pglob.gl_pathc;
 
391
#else
 
392
    count = (size_t) gl->pglob.gl_matchc;
 
393
#endif
 
394
 
 
395
    if (gl->n < count) {
280
396
 
281
397
        name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
282
398
        name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
301
417
{
302
418
    struct flock  fl;
303
419
 
304
 
    fl.l_start = 0;
305
 
    fl.l_len = 0;
306
 
    fl.l_pid = 0;
 
420
    ngx_memzero(&fl, sizeof(struct flock));
307
421
    fl.l_type = F_WRLCK;
308
422
    fl.l_whence = SEEK_SET;
309
423
 
320
434
{
321
435
    struct flock  fl;
322
436
 
323
 
    fl.l_start = 0;
324
 
    fl.l_len = 0;
325
 
    fl.l_pid = 0;
 
437
    ngx_memzero(&fl, sizeof(struct flock));
326
438
    fl.l_type = F_WRLCK;
327
439
    fl.l_whence = SEEK_SET;
328
440
 
339
451
{
340
452
    struct flock  fl;
341
453
 
342
 
    fl.l_start = 0;
343
 
    fl.l_len = 0;
344
 
    fl.l_pid = 0;
 
454
    ngx_memzero(&fl, sizeof(struct flock));
345
455
    fl.l_type = F_UNLCK;
346
456
    fl.l_whence = SEEK_SET;
347
457
 
351
461
 
352
462
    return 0;
353
463
}
 
464
 
 
465
 
 
466
#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
 
467
 
 
468
ngx_int_t
 
469
ngx_read_ahead(ngx_fd_t fd, size_t n)
 
470
{
 
471
    int  err;
 
472
 
 
473
    err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
 
474
 
 
475
    if (err == 0) {
 
476
        return 0;
 
477
    }
 
478
 
 
479
    ngx_set_errno(err);
 
480
    return NGX_FILE_ERROR;
 
481
}
 
482
 
 
483
#endif
 
484
 
 
485
 
 
486
#if (NGX_HAVE_O_DIRECT)
 
487
 
 
488
ngx_int_t
 
489
ngx_directio_on(ngx_fd_t fd)
 
490
{
 
491
    int  flags;
 
492
 
 
493
    flags = fcntl(fd, F_GETFL);
 
494
 
 
495
    if (flags == -1) {
 
496
        return NGX_FILE_ERROR;
 
497
    }
 
498
 
 
499
    return fcntl(fd, F_SETFL, flags | O_DIRECT);
 
500
}
 
501
 
 
502
 
 
503
ngx_int_t
 
504
ngx_directio_off(ngx_fd_t fd)
 
505
{
 
506
    int  flags;
 
507
 
 
508
    flags = fcntl(fd, F_GETFL);
 
509
 
 
510
    if (flags == -1) {
 
511
        return NGX_FILE_ERROR;
 
512
    }
 
513
 
 
514
    return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
 
515
}
 
516
 
 
517
#endif
 
518
 
 
519
 
 
520
#if (NGX_HAVE_STATFS)
 
521
 
 
522
size_t
 
523
ngx_fs_bsize(u_char *name)
 
524
{
 
525
    struct statfs  fs;
 
526
 
 
527
    if (statfs((char *) name, &fs) == -1) {
 
528
        return 512;
 
529
    }
 
530
 
 
531
    if ((fs.f_bsize % 512) != 0) {
 
532
        return 512;
 
533
    }
 
534
 
 
535
    return (size_t) fs.f_bsize;
 
536
}
 
537
 
 
538
#elif (NGX_HAVE_STATVFS)
 
539
 
 
540
size_t
 
541
ngx_fs_bsize(u_char *name)
 
542
{
 
543
    struct statvfs  fs;
 
544
 
 
545
    if (statvfs((char *) name, &fs) == -1) {
 
546
        return 512;
 
547
    }
 
548
 
 
549
    if ((fs.f_frsize % 512) != 0) {
 
550
        return 512;
 
551
    }
 
552
 
 
553
    return (size_t) fs.f_frsize;
 
554
}
 
555
 
 
556
#else
 
557
 
 
558
size_t
 
559
ngx_fs_bsize(u_char *name)
 
560
{
 
561
    return 512;
 
562
}
 
563
 
 
564
#endif