]> git.kaiwu.me - nginx.git/commitdiff
Dav: changed ngx_copy_file() to preserve access and mtime.
authorMaxim Dounin <mdounin@mdounin.ru>
Tue, 31 Jul 2018 23:12:11 +0000 (02:12 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Tue, 31 Jul 2018 23:12:11 +0000 (02:12 +0300)
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.

src/core/ngx_file.c

index 57ad042debaa2d3722760ed64cdd6f98ce246828..56780303bc1f349b7bee8072b08b249e6732f784 100644 (file)
@@ -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;