comparison src/core/ngx_open_file_cache.c @ 662:e5fa0a4a7d27 NGINX_1_1_15

nginx 1.1.15 *) Feature: the "disable_symlinks" directive. *) Feature: the "proxy_cookie_domain" and "proxy_cookie_path" directives. *) Bugfix: nginx might log incorrect error "upstream prematurely closed connection" instead of correct "upstream sent too big header" one. Thanks to Feibo Li. *) Bugfix: nginx could not be built with the ngx_http_perl_module if the --with-openssl option was used. *) Bugfix: internal redirects to named locations were not limited. *) Bugfix: calling $r->flush() multiple times might cause errors in the ngx_http_gzip_filter_module. *) Bugfix: temporary files might be not removed if the "proxy_store" directive were used with SSI includes. *) Bugfix: in some cases non-cacheable variables (such as the $args variable) returned old empty cached value. *) Bugfix: a segmentation fault might occur in a worker process if too many SSI subrequests were issued simultaneously; the bug had appeared in 0.7.25.
author Igor Sysoev <http://sysoev.ru>
date Wed, 15 Feb 2012 00:00:00 +0400
parents d0f7a625f27c
children f5b859b2f097
comparison
equal deleted inserted replaced
661:b49c1751031c 662:e5fa0a4a7d27
20 20
21 #define NGX_MIN_READ_AHEAD (128 * 1024) 21 #define NGX_MIN_READ_AHEAD (128 * 1024)
22 22
23 23
24 static void ngx_open_file_cache_cleanup(void *data); 24 static void ngx_open_file_cache_cleanup(void *data);
25 static ngx_int_t ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, 25 #if (NGX_HAVE_OPENAT)
26 ngx_log_t *log); 26 static ngx_fd_t ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
27 ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log);
28 #endif
29 static ngx_fd_t ngx_open_file_wrapper(ngx_str_t *name,
30 ngx_open_file_info_t *of, ngx_int_t mode, ngx_int_t create,
31 ngx_int_t access, ngx_log_t *log);
32 static ngx_int_t ngx_file_info_wrapper(ngx_str_t *name,
33 ngx_open_file_info_t *of, ngx_file_info_t *fi, ngx_log_t *log);
34 static ngx_int_t ngx_open_and_stat_file(ngx_str_t *name,
35 ngx_open_file_info_t *of, ngx_log_t *log);
27 static void ngx_open_file_add_event(ngx_open_file_cache_t *cache, 36 static void ngx_open_file_add_event(ngx_open_file_cache_t *cache,
28 ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log); 37 ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log);
29 static void ngx_open_file_cleanup(void *data); 38 static void ngx_open_file_cleanup(void *data);
30 static void ngx_close_cached_file(ngx_open_file_cache_t *cache, 39 static void ngx_close_cached_file(ngx_open_file_cache_t *cache,
31 ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log); 40 ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log);
145 154
146 if (cache == NULL) { 155 if (cache == NULL) {
147 156
148 if (of->test_only) { 157 if (of->test_only) {
149 158
150 if (ngx_file_info(name->data, &fi) == NGX_FILE_ERROR) { 159 if (ngx_file_info_wrapper(name, of, &fi, pool->log)
151 of->err = ngx_errno; 160 == NGX_FILE_ERROR)
152 of->failed = ngx_file_info_n; 161 {
153 return NGX_ERROR; 162 return NGX_ERROR;
154 } 163 }
155 164
156 of->uniq = ngx_file_uniq(&fi); 165 of->uniq = ngx_file_uniq(&fi);
157 of->mtime = ngx_file_mtime(&fi); 166 of->mtime = ngx_file_mtime(&fi);
168 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); 177 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
169 if (cln == NULL) { 178 if (cln == NULL) {
170 return NGX_ERROR; 179 return NGX_ERROR;
171 } 180 }
172 181
173 rc = ngx_open_and_stat_file(name->data, of, pool->log); 182 rc = ngx_open_and_stat_file(name, of, pool->log);
174 183
175 if (rc == NGX_OK && !of->is_dir) { 184 if (rc == NGX_OK && !of->is_dir) {
176 cln->handler = ngx_pool_cleanup_file; 185 cln->handler = ngx_pool_cleanup_file;
177 clnf = cln->data; 186 clnf = cln->data;
178 187
203 212
204 if (file->fd == NGX_INVALID_FILE && file->err == 0 && !file->is_dir) { 213 if (file->fd == NGX_INVALID_FILE && file->err == 0 && !file->is_dir) {
205 214
206 /* file was not used often enough to keep open */ 215 /* file was not used often enough to keep open */
207 216
208 rc = ngx_open_and_stat_file(name->data, of, pool->log); 217 rc = ngx_open_and_stat_file(name, of, pool->log);
209 218
210 if (rc != NGX_OK && (of->err == 0 || !of->errors)) { 219 if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
211 goto failed; 220 goto failed;
212 } 221 }
213 222
215 } 224 }
216 225
217 if (file->use_event 226 if (file->use_event
218 || (file->event == NULL 227 || (file->event == NULL
219 && (of->uniq == 0 || of->uniq == file->uniq) 228 && (of->uniq == 0 || of->uniq == file->uniq)
220 && now - file->created < of->valid)) 229 && now - file->created < of->valid
230 #if (NGX_HAVE_OPENAT)
231 && of->disable_symlinks == file->disable_symlinks
232 #endif
233 ))
221 { 234 {
222 if (file->err == 0) { 235 if (file->err == 0) {
223 236
224 of->fd = file->fd; 237 of->fd = file->fd;
225 of->uniq = file->uniq; 238 of->uniq = file->uniq;
237 ngx_open_file_add_event(cache, file, of, pool->log); 250 ngx_open_file_add_event(cache, file, of, pool->log);
238 } 251 }
239 252
240 } else { 253 } else {
241 of->err = file->err; 254 of->err = file->err;
255 #if (NGX_HAVE_OPENAT)
256 of->failed = file->disable_symlinks ? ngx_openat_file_n
257 : ngx_open_file_n;
258 #else
242 of->failed = ngx_open_file_n; 259 of->failed = ngx_open_file_n;
260 #endif
243 } 261 }
244 262
245 goto found; 263 goto found;
246 } 264 }
247 265
261 } 279 }
262 280
263 of->fd = file->fd; 281 of->fd = file->fd;
264 of->uniq = file->uniq; 282 of->uniq = file->uniq;
265 283
266 rc = ngx_open_and_stat_file(name->data, of, pool->log); 284 rc = ngx_open_and_stat_file(name, of, pool->log);
267 285
268 if (rc != NGX_OK && (of->err == 0 || !of->errors)) { 286 if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
269 goto failed; 287 goto failed;
270 } 288 }
271 289
309 327
310 ngx_open_file_del_event(file); 328 ngx_open_file_del_event(file);
311 329
312 if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { 330 if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
313 ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno, 331 ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
314 ngx_close_file_n " \"%s\" failed", 332 ngx_close_file_n " \"%V\" failed", name);
315 name->data);
316 } 333 }
317 334
318 goto add_event; 335 goto add_event;
319 } 336 }
320 337
327 goto create; 344 goto create;
328 } 345 }
329 346
330 /* not found */ 347 /* not found */
331 348
332 rc = ngx_open_and_stat_file(name->data, of, pool->log); 349 rc = ngx_open_and_stat_file(name, of, pool->log);
333 350
334 if (rc != NGX_OK && (of->err == 0 || !of->errors)) { 351 if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
335 goto failed; 352 goto failed;
336 } 353 }
337 354
374 391
375 update: 392 update:
376 393
377 file->fd = of->fd; 394 file->fd = of->fd;
378 file->err = of->err; 395 file->err = of->err;
396 #if (NGX_HAVE_OPENAT)
397 file->disable_symlinks = of->disable_symlinks;
398 #endif
379 399
380 if (of->err == 0) { 400 if (of->err == 0) {
381 file->uniq = of->uniq; 401 file->uniq = of->uniq;
382 file->mtime = of->mtime; 402 file->mtime = of->mtime;
383 file->size = of->size; 403 file->size = of->size;
450 } 470 }
451 471
452 if (of->fd != NGX_INVALID_FILE) { 472 if (of->fd != NGX_INVALID_FILE) {
453 if (ngx_close_file(of->fd) == NGX_FILE_ERROR) { 473 if (ngx_close_file(of->fd) == NGX_FILE_ERROR) {
454 ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno, 474 ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
455 ngx_close_file_n " \"%s\" failed", name->data); 475 ngx_close_file_n " \"%V\" failed", name);
456 } 476 }
457 } 477 }
458 478
459 return NGX_ERROR; 479 return NGX_ERROR;
460 } 480 }
461 481
462 482
483 #if (NGX_HAVE_OPENAT)
484
485 static ngx_fd_t
486 ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
487 ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log)
488 {
489 ngx_fd_t fd;
490 ngx_err_t err;
491 ngx_file_info_t fi, atfi;
492
493 /*
494 * To allow symlinks with the same owner, use openat() (followed
495 * by fstat()) and fstatat(AT_SYMLINK_NOFOLLOW), and then compare
496 * uids between fstat() and fstatat().
497 *
498 * As there is a race between openat() and fstatat() we don't
499 * know if openat() in fact opened symlink or not. Therefore,
500 * we have to compare uids even if fstatat() reports the opened
501 * component isn't a symlink (as we don't know whether it was
502 * symlink during openat() or not).
503 */
504
505 fd = ngx_openat_file(at_fd, name, mode, create, access);
506
507 if (fd == NGX_FILE_ERROR) {
508 return NGX_FILE_ERROR;
509 }
510
511 if (ngx_file_at_info(at_fd, name, &atfi, AT_SYMLINK_NOFOLLOW)
512 == NGX_FILE_ERROR)
513 {
514 err = ngx_errno;
515 goto failed;
516 }
517
518 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
519 err = ngx_errno;
520 goto failed;
521 }
522
523 if (fi.st_uid != atfi.st_uid) {
524 err = NGX_ELOOP;
525 goto failed;
526 }
527
528 return fd;
529
530 failed:
531
532 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
533 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
534 ngx_close_file_n " \"%V\" failed", name);
535 }
536
537 ngx_set_errno(err);
538
539 return NGX_INVALID_FILE;
540 }
541
542 #endif
543
544
545 static ngx_fd_t
546 ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
547 ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log)
548 {
549 ngx_fd_t fd;
550
551 #if !(NGX_HAVE_OPENAT)
552
553 fd = ngx_open_file(name->data, mode, create, access);
554
555 if (fd == NGX_INVALID_FILE) {
556 of->err = ngx_errno;
557 of->failed = ngx_open_file_n;
558 return NGX_INVALID_FILE;
559 }
560
561 return fd;
562
563 #else
564
565 u_char *p, *cp, *end;
566 ngx_fd_t at_fd;
567 ngx_str_t at_name;
568 ngx_file_info_t fi;
569
570 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
571 fd = ngx_open_file(name->data, mode, create, access);
572
573 if (fd == NGX_INVALID_FILE) {
574 of->err = ngx_errno;
575 of->failed = ngx_open_file_n;
576 return NGX_INVALID_FILE;
577 }
578
579 return fd;
580 }
581
582 p = name->data;
583 end = p + name->len;
584
585 at_fd = AT_FDCWD;
586 at_name = *name;
587
588 if (p[0] == '/') {
589 at_fd = ngx_openat_file(at_fd, "/",
590 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
591 NGX_FILE_OPEN, 0);
592
593 if (at_fd == NGX_FILE_ERROR) {
594 of->err = ngx_errno;
595 of->failed = ngx_openat_file_n;
596 return NGX_FILE_ERROR;
597 }
598
599 at_name.len = 1;
600 p++;
601 }
602
603 for ( ;; ) {
604 cp = ngx_strlchr(p, end, '/');
605 if (cp == NULL) {
606 break;
607 }
608
609 if (cp == p) {
610 p++;
611 continue;
612 }
613
614 *cp = '\0';
615
616 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
617 fd = ngx_openat_file_owner(at_fd, p,
618 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
619 NGX_FILE_OPEN, 0, log);
620
621 } else {
622 fd = ngx_openat_file(at_fd, p,
623 NGX_FILE_RDONLY|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW,
624 NGX_FILE_OPEN, 0);
625 }
626
627 *cp = '/';
628
629 if (fd == NGX_INVALID_FILE) {
630 of->err = ngx_errno;
631 of->failed = ngx_openat_file_n;
632 goto failed;
633 }
634
635 if (at_fd != AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
636 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
637 ngx_close_file_n " \"%V\" failed", at_name);
638 }
639
640 p = cp + 1;
641 at_fd = fd;
642 at_name.len = cp - at_name.data;
643 }
644
645 if (p == end && at_fd != AT_FDCWD) {
646
647 /*
648 * If pathname ends with a trailing slash, check if last path
649 * component is a directory; if not, fail with ENOTDIR as per
650 * POSIX.
651 *
652 * We use separate check instead of O_DIRECTORY in the loop above,
653 * as O_DIRECTORY doesn't work on FreeBSD 8.
654 *
655 * Note this returns already opened file descriptor, with different
656 * mode/create/access. This is believed to be safe as we don't
657 * use this codepath to create directories.
658 */
659
660 if (ngx_fd_info(at_fd, &fi) == NGX_FILE_ERROR) {
661 of->err = ngx_errno;
662 of->failed = ngx_fd_info_n;
663 fd = NGX_INVALID_FILE;
664
665 goto failed;
666 }
667
668 if (ngx_is_dir(&fi)) {
669 return at_fd;
670 }
671
672 of->err = ENOTDIR;
673 of->failed = ngx_openat_file_n;
674 fd = NGX_INVALID_FILE;
675
676 goto failed;
677 }
678
679 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
680 fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log);
681
682 } else {
683 fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access);
684 }
685
686 if (fd == NGX_INVALID_FILE) {
687 of->err = ngx_errno;
688 of->failed = ngx_openat_file_n;
689 }
690
691 failed:
692
693 if (at_fd != AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
694 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
695 ngx_close_file_n " \"%V\" failed", at_name);
696 }
697
698 return fd;
699 #endif
700 }
701
702
463 static ngx_int_t 703 static ngx_int_t
464 ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log) 704 ngx_file_info_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
705 ngx_file_info_t *fi, ngx_log_t *log)
706 {
707 ngx_int_t rc;
708
709 #if !(NGX_HAVE_OPENAT)
710
711 rc = ngx_file_info(name->data, fi);
712
713 if (rc == NGX_FILE_ERROR) {
714 of->err = ngx_errno;
715 of->failed = ngx_file_info_n;
716 return NGX_FILE_ERROR;
717 }
718
719 return rc;
720
721 #else
722
723 ngx_fd_t fd;
724
725 if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
726
727 rc = ngx_file_info(name->data, fi);
728
729 if (rc == NGX_FILE_ERROR) {
730 of->err = ngx_errno;
731 of->failed = ngx_file_info_n;
732 return NGX_FILE_ERROR;
733 }
734
735 return rc;
736 }
737
738 fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
739 NGX_FILE_OPEN, 0, log);
740
741 if (fd == NGX_INVALID_FILE) {
742 return NGX_FILE_ERROR;
743 }
744
745 rc = ngx_fd_info(fd, fi);
746
747 if (rc == NGX_FILE_ERROR) {
748 of->err = ngx_errno;
749 of->failed = ngx_fd_info_n;
750 }
751
752 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
753 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
754 ngx_close_file_n " \"%V\" failed", name);
755 }
756
757 return rc;
758 #endif
759 }
760
761
762 static ngx_int_t
763 ngx_open_and_stat_file(ngx_str_t *name, ngx_open_file_info_t *of,
764 ngx_log_t *log)
465 { 765 {
466 ngx_fd_t fd; 766 ngx_fd_t fd;
467 ngx_file_info_t fi; 767 ngx_file_info_t fi;
468 768
469 if (of->fd != NGX_INVALID_FILE) { 769 if (of->fd != NGX_INVALID_FILE) {
470 770
471 if (ngx_file_info(name, &fi) == NGX_FILE_ERROR) { 771 if (ngx_file_info_wrapper(name, of, &fi, log) == NGX_FILE_ERROR) {
472 of->failed = ngx_file_info_n; 772 of->fd = NGX_INVALID_FILE;
473 goto failed; 773 return NGX_ERROR;
474 } 774 }
475 775
476 if (of->uniq == ngx_file_uniq(&fi)) { 776 if (of->uniq == ngx_file_uniq(&fi)) {
477 goto done; 777 goto done;
478 } 778 }
479 779
480 } else if (of->test_dir) { 780 } else if (of->test_dir) {
481 781
482 if (ngx_file_info(name, &fi) == NGX_FILE_ERROR) { 782 if (ngx_file_info_wrapper(name, of, &fi, log) == NGX_FILE_ERROR) {
483 of->failed = ngx_file_info_n; 783 of->fd = NGX_INVALID_FILE;
484 goto failed; 784 return NGX_ERROR;
485 } 785 }
486 786
487 if (ngx_is_dir(&fi)) { 787 if (ngx_is_dir(&fi)) {
488 goto done; 788 goto done;
489 } 789 }
494 /* 794 /*
495 * Use non-blocking open() not to hang on FIFO files, etc. 795 * Use non-blocking open() not to hang on FIFO files, etc.
496 * This flag has no effect on a regular files. 796 * This flag has no effect on a regular files.
497 */ 797 */
498 798
499 fd = ngx_open_file(name, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, 799 fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
500 NGX_FILE_OPEN, 0); 800 NGX_FILE_OPEN, 0, log);
501 801
502 } else { 802 } else {
503 fd = ngx_open_file(name, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN, 803 fd = ngx_open_file_wrapper(name, of, NGX_FILE_APPEND,
504 NGX_FILE_DEFAULT_ACCESS); 804 NGX_FILE_CREATE_OR_OPEN,
805 NGX_FILE_DEFAULT_ACCESS, log);
505 } 806 }
506 807
507 if (fd == NGX_INVALID_FILE) { 808 if (fd == NGX_INVALID_FILE) {
508 of->failed = ngx_open_file_n; 809 of->fd = NGX_INVALID_FILE;
509 goto failed; 810 return NGX_ERROR;
510 } 811 }
511 812
512 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { 813 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
513 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, 814 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
514 ngx_fd_info_n " \"%s\" failed", name); 815 ngx_fd_info_n " \"%V\" failed", name);
515 816
516 if (ngx_close_file(fd) == NGX_FILE_ERROR) { 817 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
517 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 818 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
518 ngx_close_file_n " \"%s\" failed", name); 819 ngx_close_file_n " \"%V\" failed", name);
519 } 820 }
520 821
521 of->fd = NGX_INVALID_FILE; 822 of->fd = NGX_INVALID_FILE;
522 823
523 return NGX_ERROR; 824 return NGX_ERROR;
524 } 825 }
525 826
526 if (ngx_is_dir(&fi)) { 827 if (ngx_is_dir(&fi)) {
527 if (ngx_close_file(fd) == NGX_FILE_ERROR) { 828 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
528 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 829 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
529 ngx_close_file_n " \"%s\" failed", name); 830 ngx_close_file_n " \"%V\" failed", name);
530 } 831 }
531 832
532 of->fd = NGX_INVALID_FILE; 833 of->fd = NGX_INVALID_FILE;
533 834
534 } else { 835 } else {
535 of->fd = fd; 836 of->fd = fd;
536 837
537 if (of->read_ahead && ngx_file_size(&fi) > NGX_MIN_READ_AHEAD) { 838 if (of->read_ahead && ngx_file_size(&fi) > NGX_MIN_READ_AHEAD) {
538 if (ngx_read_ahead(fd, of->read_ahead) == NGX_ERROR) { 839 if (ngx_read_ahead(fd, of->read_ahead) == NGX_ERROR) {
539 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 840 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
540 ngx_read_ahead_n " \"%s\" failed", name); 841 ngx_read_ahead_n " \"%V\" failed", name);
541 } 842 }
542 } 843 }
543 844
544 if (of->directio <= ngx_file_size(&fi)) { 845 if (of->directio <= ngx_file_size(&fi)) {
545 if (ngx_directio_on(fd) == NGX_FILE_ERROR) { 846 if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
546 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 847 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
547 ngx_directio_on_n " \"%s\" failed", name); 848 ngx_directio_on_n " \"%V\" failed", name);
548 849
549 } else { 850 } else {
550 of->is_directio = 1; 851 of->is_directio = 1;
551 } 852 }
552 } 853 }
562 of->is_file = ngx_is_file(&fi); 863 of->is_file = ngx_is_file(&fi);
563 of->is_link = ngx_is_link(&fi); 864 of->is_link = ngx_is_link(&fi);
564 of->is_exec = ngx_is_exec(&fi); 865 of->is_exec = ngx_is_exec(&fi);
565 866
566 return NGX_OK; 867 return NGX_OK;
567
568 failed:
569
570 of->fd = NGX_INVALID_FILE;
571 of->err = ngx_errno;
572
573 return NGX_ERROR;
574 } 868 }
575 869
576 870
577 /* 871 /*
578 * we ignore any possible event setting error and 872 * we ignore any possible event setting error and