comparison src/core/ngx_file.c @ 356:b743d290eb3b NGINX_0_6_22

nginx 0.6.22 *) Change: now all ngx_http_perl_module methods return values copied to perl's allocated memory. *) Bugfix: if nginx was built with ngx_http_perl_module, the perl before 5.8.6 was used, and perl supported threads, then during reconfiguration the master process aborted; bug appeared in 0.5.9. Thanks to Boris Zhmurov. *) Bugfix: the ngx_http_perl_module methods may get invalid values of the regex captures. *) Bugfix: a segmentation fault occurred in worker process, if the $r->has_request_body() method was called for a request whose small request body was already received. *) Bugfix: large_client_header_buffers did not freed before going to keep-alive state. Thanks to Olexander Shtepa. *) Bugfix: the last address was missed in the $upstream_addr variable; bug appeared in 0.6.18. *) Bugfix: the "fastcgi_catch_stderr" directive did return error code; now it returns 502 code, that can be rerouted to a next server using the "fastcgi_next_upstream invalid_header" directive. *) Bugfix: a segmentation fault occurred in master process if the "fastcgi_catch_stderr" directive was used; bug appeared in 0.6.10. Thanks to Manlio Perillo.
author Igor Sysoev <http://sysoev.ru>
date Wed, 19 Dec 2007 00:00:00 +0300
parents f7cd062ee035
children 54fad6c4b555
comparison
equal deleted inserted replaced
355:3ac45897a61c 356:b743d290eb3b
59 59
60 ngx_memcpy(file->name.data, path->name.data, path->name.len); 60 ngx_memcpy(file->name.data, path->name.data, path->name.len);
61 61
62 n = (uint32_t) ngx_next_temp_number(0); 62 n = (uint32_t) ngx_next_temp_number(0);
63 63
64 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
65 if (cln == NULL) {
66 return NGX_ERROR;
67 }
68
64 for ( ;; ) { 69 for ( ;; ) {
65 (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len, 70 (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len,
66 "%010uD%Z", n); 71 "%010uD%Z", n);
67 72
68 ngx_create_hashed_filename(file, path); 73 ngx_create_hashed_filename(path, file->name.data, file->name.len);
69 74
70 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); 75 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
71 if (cln == NULL) { 76 "hashed path: %s", file->name.data);
72 return NGX_ERROR;
73 }
74 77
75 file->fd = ngx_open_tempfile(file->name.data, persistent, access); 78 file->fd = ngx_open_tempfile(file->name.data, persistent, access);
76 79
77 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, 80 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
78 "temp fd:%d", file->fd); 81 "temp fd:%d", file->fd);
115 } 118 }
116 } 119 }
117 120
118 121
119 void 122 void
120 ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path) 123 ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len)
121 { 124 {
122 size_t name, pos, level; 125 size_t i, level;
123 ngx_uint_t i; 126 ngx_uint_t n;
124 127
125 name = file->name.len; 128 i = path->name.len + 1;
126 pos = path->name.len + 1; 129
127 130 file[path->name.len + path->len] = '/';
128 file->name.data[path->name.len + path->len] = '/'; 131
129 132 for (n = 0; n < 3; n++) {
130 for (i = 0; i < 3; i++) { 133 level = path->level[n];
131 level = path->level[i];
132 134
133 if (level == 0) { 135 if (level == 0) {
134 break; 136 break;
135 } 137 }
136 138
137 name -= level; 139 len -= level;
138 file->name.data[pos - 1] = '/'; 140 file[i - 1] = '/';
139 ngx_memcpy(&file->name.data[pos], &file->name.data[name], level); 141 ngx_memcpy(&file[i], &file[len], level);
140 pos += level + 1; 142 i += level + 1;
141 } 143 }
142
143 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
144 "hashed path: %s", file->name.data);
145 } 144 }
146 145
147 146
148 ngx_int_t 147 ngx_int_t
149 ngx_create_path(ngx_file_t *file, ngx_path_t *path) 148 ngx_create_path(ngx_file_t *file, ngx_path_t *path)
423 ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user) 422 ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
424 { 423 {
425 ngx_err_t err; 424 ngx_err_t err;
426 ngx_uint_t i; 425 ngx_uint_t i;
427 ngx_path_t **path; 426 ngx_path_t **path;
428 #if !(NGX_WIN32)
429 ngx_file_info_t fi;
430 #endif
431 427
432 path = cycle->pathes.elts; 428 path = cycle->pathes.elts;
433 for (i = 0; i < cycle->pathes.nelts; i++) { 429 for (i = 0; i < cycle->pathes.nelts; i++) {
434 430
435 if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) { 431 if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) {
445 if (user == (ngx_uid_t) NGX_CONF_UNSET_UINT) { 441 if (user == (ngx_uid_t) NGX_CONF_UNSET_UINT) {
446 continue; 442 continue;
447 } 443 }
448 444
449 #if !(NGX_WIN32) 445 #if !(NGX_WIN32)
446 {
447 ngx_file_info_t fi;
450 448
451 if (ngx_file_info((const char *) path[i]->name.data, &fi) == -1) { 449 if (ngx_file_info((const char *) path[i]->name.data, &fi) == -1) {
452 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 450 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
453 ngx_file_info_n " \"%s\" failed", path[i]->name.data); 451 ngx_file_info_n " \"%s\" failed", path[i]->name.data);
454 return NGX_ERROR; 452 return NGX_ERROR;
472 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 470 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
473 "chmod() \"%s\" failed", path[i]->name.data); 471 "chmod() \"%s\" failed", path[i]->name.data);
474 return NGX_ERROR; 472 return NGX_ERROR;
475 } 473 }
476 } 474 }
477 475 }
478 #endif 476 #endif
479 } 477 }
480 478
481 return NGX_OK; 479 return NGX_OK;
482 } 480 }
483 481
482
483 ngx_int_t
484 ngx_create_path_and_rename_file(ngx_str_t *src, ngx_str_t *to,
485 ngx_uint_t access, ngx_uint_t full_path, ngx_uint_t delete, ngx_log_t *log)
486 {
487 ngx_err_t err;
488
489 #if !(NGX_WIN32)
490
491 if (ngx_change_file_access(src->data, access) == NGX_FILE_ERROR) {
492 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
493 ngx_change_file_access_n " \"%s\" failed", src->data);
494 err = 0;
495 goto failed;
496 }
497
498 #endif
499
500 if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
501 return NGX_OK;
502 }
503
504 err = ngx_errno;
505
506 if (err == NGX_ENOENT) {
507
508 if (!full_path) {
509 goto failed;
510 }
511
512 err = ngx_create_full_path(to->data, ngx_dir_access(access));
513
514 if (err) {
515 ngx_log_error(NGX_LOG_CRIT, log, err,
516 ngx_create_dir_n " \"%s\" failed", to->data);
517 err = 0;
518 goto failed;
519 }
520
521 if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
522 return NGX_OK;
523 }
524
525 err = ngx_errno;
526 goto failed;
527 }
528
529 #if (NGX_WIN32)
530
531 if (err == NGX_EEXIST) {
532 if (ngx_win32_rename_file(src, to, log) == NGX_OK) {
533
534 if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
535 return NGX_OK;
536 }
537
538 err = ngx_errno;
539
540 } else {
541 err = 0;
542 }
543 }
544
545 #endif
546
547 failed:
548
549 if (delete) {
550 if (ngx_delete_file(src->data) == NGX_FILE_ERROR) {
551 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
552 ngx_delete_file_n " \"%s\" failed", src->data);
553 }
554 }
555
556 if (err) {
557 ngx_log_error(NGX_LOG_CRIT, log, err,
558 ngx_rename_file_n " \"%s\" to \"%s\" failed",
559 src->data, to->data);
560 }
561
562 return NGX_ERROR;
563 }
564
565
566 /*
567 * ctx->init_handler() - see ctx->alloc
568 * ctx->file_handler() - file handler
569 * ctx->pre_tree_handler() - handler is called before entering directory
570 * ctx->post_tree_handler() - handler is called after leaving directory
571 * ctx->spec_handler() - special (socket, FIFO, etc.) file handler
572 *
573 * ctx->data - some data structure, it may be the same on all levels, or
574 * reallocated if ctx->alloc is nonzero
575 *
576 * ctx->alloc - a size of data structure that is allocated at every level
577 * and is initilialized by ctx->init_handler()
578 *
579 * ctx->log - a log
580 *
581 * on fatal (memory) error handler must return NGX_ABORT to stop walking tree
582 */
484 583
485 ngx_int_t 584 ngx_int_t
486 ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree) 585 ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree)
487 { 586 {
488 void *data, *prev; 587 void *data, *prev;