aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_file.c
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2018-08-01 02:12:11 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2018-08-01 02:12:11 +0300
commit9e0d1236f16ad51828b91ca2ded211c9a96cba72 (patch)
tree3326f6d6d82f44685bcf12eb67ce63fbafa6357d /src/core/ngx_file.c
parent6bff9c9967dcac5fa03a0c1de6af0a1285c3d829 (diff)
downloadnginx-9e0d1236f16ad51828b91ca2ded211c9a96cba72.tar.gz
nginx-9e0d1236f16ad51828b91ca2ded211c9a96cba72.zip
Dav: changed ngx_copy_file() to preserve access and mtime.
This fixes wrong permissions and file time after cross-device MOVE in the DAV module (ticket #1577). Broken in 8101d9101ed8 (0.8.9) when cross-device copying was introduced in ngx_ext_rename_file(). With this change, ngx_copy_file() always calls ngx_set_file_time(), either with the time provided, or with the time from the original file. This is considered acceptable given that copying the file is costly anyway, and optimizing cases when we do not need to preserve time will require interface changes.
Diffstat (limited to 'src/core/ngx_file.c')
-rw-r--r--src/core/ngx_file.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 57ad042de..56780303b 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -796,10 +796,12 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
{
char *buf;
off_t size;
+ time_t time;
size_t len;
ssize_t n;
ngx_fd_t fd, nfd;
ngx_int_t rc;
+ ngx_uint_t access;
ngx_file_info_t fi;
rc = NGX_ERROR;
@@ -814,8 +816,10 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
goto failed;
}
- if (cf->size != -1) {
+ if (cf->size != -1 && cf->access != 0 && cf->time != -1) {
size = cf->size;
+ access = cf->access;
+ time = cf->time;
} else {
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
@@ -825,7 +829,9 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
goto failed;
}
- size = ngx_file_size(&fi);
+ size = (cf->size != -1) ? cf->size : ngx_file_size(&fi);
+ access = cf->access ? cf->access : ngx_file_access(&fi);
+ time = (cf->time != -1) ? cf->time : ngx_file_mtime(&fi);
}
len = cf->buf_size ? cf->buf_size : 65536;
@@ -839,7 +845,7 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
goto failed;
}
- nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_TRUNCATE, cf->access);
+ nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_TRUNCATE, access);
if (nfd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
@@ -886,12 +892,10 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
size -= n;
}
- if (cf->time != -1) {
- if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", to);
- goto failed;
- }
+ if (ngx_set_file_time(to, nfd, time) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_set_file_time_n " \"%s\" failed", to);
+ goto failed;
}
rc = NGX_OK;