mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	Merge #6422 from ZyX-I/fix-6420
eval,fileio: Omit additional fsync() call
This commit is contained in:
		@@ -17289,7 +17289,7 @@ static bool write_list(FileDescriptor *const fp, const list_T *const list,
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if ((error = file_fsync(fp)) != 0) {
 | 
					  if ((error = file_flush(fp)) != 0) {
 | 
				
			||||||
    goto write_list_error;
 | 
					    goto write_list_error;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
@@ -17439,21 +17439,21 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
 | 
				
			|||||||
  if (fname == NULL) {
 | 
					  if (fname == NULL) {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  FileDescriptor *fp;
 | 
					  FileDescriptor fp;
 | 
				
			||||||
  int error;
 | 
					  int error;
 | 
				
			||||||
  rettv->vval.v_number = -1;
 | 
					  rettv->vval.v_number = -1;
 | 
				
			||||||
  if (*fname == NUL) {
 | 
					  if (*fname == NUL) {
 | 
				
			||||||
    EMSG(_("E482: Can't open file with an empty name"));
 | 
					    EMSG(_("E482: Can't open file with an empty name"));
 | 
				
			||||||
  } else if ((fp = file_open_new(&error, fname,
 | 
					  } else if ((error = file_open(&fp, fname,
 | 
				
			||||||
                                ((append ? kFileAppend : kFileTruncate)
 | 
					                                ((append ? kFileAppend : kFileTruncate)
 | 
				
			||||||
                                  | kFileCreate), 0666)) == NULL) {
 | 
					                                 | kFileCreate), 0666)) != 0) {
 | 
				
			||||||
    emsgf(_("E482: Can't open file %s for writing: %s"),
 | 
					    emsgf(_("E482: Can't open file %s for writing: %s"),
 | 
				
			||||||
          fname, os_strerror(error));
 | 
					          fname, os_strerror(error));
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    if (write_list(fp, argvars[0].vval.v_list, binary)) {
 | 
					    if (write_list(&fp, argvars[0].vval.v_list, binary)) {
 | 
				
			||||||
      rettv->vval.v_number = 0;
 | 
					      rettv->vval.v_number = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if ((error = file_free(fp)) != 0) {
 | 
					    if ((error = file_close(&fp)) != 0) {
 | 
				
			||||||
      emsgf(_("E80: Error when closing file %s: %s"),
 | 
					      emsgf(_("E80: Error when closing file %s: %s"),
 | 
				
			||||||
            fname, os_strerror(error));
 | 
					            fname, os_strerror(error));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,21 +143,36 @@ int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
 | 
				
			|||||||
/// @param[in,out]  fp  File to work with.
 | 
					/// @param[in,out]  fp  File to work with.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// @return 0 or error code.
 | 
					/// @return 0 or error code.
 | 
				
			||||||
int file_fsync(FileDescriptor *const fp)
 | 
					int file_flush(FileDescriptor *const fp)
 | 
				
			||||||
  FUNC_ATTR_NONNULL_ALL
 | 
					  FUNC_ATTR_NONNULL_ALL
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (!fp->wr) {
 | 
					  if (!fp->wr) {
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  file_rb_write_full_cb(fp->rv, fp);
 | 
					  file_rb_write_full_cb(fp->rv, fp);
 | 
				
			||||||
  if (fp->_error != 0) {
 | 
					 | 
				
			||||||
  const int error = fp->_error;
 | 
					  const int error = fp->_error;
 | 
				
			||||||
  fp->_error = 0;
 | 
					  fp->_error = 0;
 | 
				
			||||||
  return error;
 | 
					  return error;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
  const int error = os_fsync(fp->fd);
 | 
					
 | 
				
			||||||
  if (error != UV_EINVAL && error != UV_EROFS) {
 | 
					/// Flush file modifications to disk and run fsync()
 | 
				
			||||||
    return error;
 | 
					///
 | 
				
			||||||
 | 
					/// @param[in,out]  fp  File to work with.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @return 0 or error code.
 | 
				
			||||||
 | 
					int file_fsync(FileDescriptor *const fp)
 | 
				
			||||||
 | 
					  FUNC_ATTR_NONNULL_ALL
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (!fp->wr) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const int flush_error = file_flush(fp);
 | 
				
			||||||
 | 
					  if (flush_error != 0) {
 | 
				
			||||||
 | 
					    return flush_error;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const int fsync_error = os_fsync(fp->fd);
 | 
				
			||||||
 | 
					  if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) {
 | 
				
			||||||
 | 
					    return fsync_error;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,10 @@ local function file_read(fp, size)
 | 
				
			|||||||
  return ret1, ret2
 | 
					  return ret1, ret2
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function file_flush(fp)
 | 
				
			||||||
 | 
					  return m.file_flush(fp)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function file_fsync(fp)
 | 
					local function file_fsync(fp)
 | 
				
			||||||
  return m.file_fsync(fp)
 | 
					  return m.file_fsync(fp)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
@@ -244,6 +248,21 @@ describe('file_fsync', function()
 | 
				
			|||||||
  end)
 | 
					  end)
 | 
				
			||||||
end)
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('file_flush', function()
 | 
				
			||||||
 | 
					  itp('can flush writes to disk', function()
 | 
				
			||||||
 | 
					    local err, fp = file_open(filec, m.kFileCreateOnly, 384)
 | 
				
			||||||
 | 
					    eq(0, file_flush(fp))
 | 
				
			||||||
 | 
					    eq(0, err)
 | 
				
			||||||
 | 
					    eq(0, lfs.attributes(filec).size)
 | 
				
			||||||
 | 
					    local wsize = file_write(fp, 'test')
 | 
				
			||||||
 | 
					    eq(4, wsize)
 | 
				
			||||||
 | 
					    eq(0, lfs.attributes(filec).size)
 | 
				
			||||||
 | 
					    eq(0, file_flush(fp))
 | 
				
			||||||
 | 
					    eq(wsize, lfs.attributes(filec).size)
 | 
				
			||||||
 | 
					    eq(0, m.file_close(fp))
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('file_read', function()
 | 
					describe('file_read', function()
 | 
				
			||||||
  itp('can read small chunks of input until eof', function()
 | 
					  itp('can read small chunks of input until eof', function()
 | 
				
			||||||
    local err, fp = file_open(file1, 0, 384)
 | 
					    local err, fp = file_open(file1, 0, 384)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user