From 9768e88f3891b5594eb2d556bd3bdf40c61d46e1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 13 Aug 2024 07:09:55 +0800 Subject: [PATCH] refactor(fileio): use os_copy() to copy file (#30030) It uses sendfile(), which is faster than combining read() and write(), and it also copies permissions. --- src/nvim/fileio.c | 43 ++----------------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index e4bdef4c7d..f6a25a27a6 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2733,53 +2733,14 @@ int vim_copyfile(const char *from, const char *to) } #endif - int perm = os_getperm(from); // For systems that support ACL: get the ACL from the original file. vim_acl_T acl = os_get_acl(from); - int fd_in = os_open(from, O_RDONLY, 0); - if (fd_in < 0) { + + if (os_copy(from, to, UV_FS_COPYFILE_EXCL) != 0) { os_free_acl(acl); return FAIL; } - // Create the new file with same permissions as the original. - int fd_out = os_open(to, O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, perm); - if (fd_out < 0) { - close(fd_in); - os_free_acl(acl); - return FAIL; - } - - // Avoid xmalloc() here as vim_rename() is called by buf_write() when nvim - // is `preserve_exit()`ing. - char *buffer = try_malloc(WRITEBUFSIZE); - if (buffer == NULL) { - close(fd_out); - close(fd_in); - os_free_acl(acl); - return FAIL; - } - - int n; - while ((n = read_eintr(fd_in, buffer, WRITEBUFSIZE)) > 0) { - if (write_eintr(fd_out, buffer, (size_t)n) != n) { - errmsg = _("E208: Error writing to \"%s\""); - break; - } - } - - xfree(buffer); - close(fd_in); - if (close(fd_out) < 0) { - errmsg = _("E209: Error closing \"%s\""); - } - if (n < 0) { - errmsg = _("E210: Error reading \"%s\""); - to = from; - } -#ifndef UNIX // For Unix os_open() already set the permission. - os_setperm(to, perm); -#endif os_set_acl(to, acl); os_free_acl(acl); if (errmsg != NULL) {