shada: Do not forget to close ShaDa reader

Previously there was file descriptor leak, not detected by sanitizers. Now it is 
file descriptor leak with a small memory leak which is detected by ASAN what 
fails one of the tests (actually, “ShaDa support code leaves .tmp.z in-place 
when there is error in original ShaDa and it has .tmp.a … .tmp.x”, but error is 
reported at the next test because leaks are not detected until Neovim exit and 
Neovim exit happens when clear()/reset() is called which happens in before_each 
only).
This commit is contained in:
ZyX 2016-06-21 22:40:09 +03:00
parent a8f3849bc0
commit 4b9d2caec2
2 changed files with 8 additions and 3 deletions

View File

@ -310,7 +310,7 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size)
break; break;
} }
read_bytes += (size_t)new_read_bytes; read_bytes += (size_t)new_read_bytes;
} while (read_bytes < size && !fp->eof); } while (read_bytes < size && !file_eof(fp));
return (ptrdiff_t)read_bytes; return (ptrdiff_t)read_bytes;
} }

View File

@ -2883,12 +2883,12 @@ int shada_write_file(const char *const file, bool nomerge)
char *const fname = shada_filename(file); char *const fname = shada_filename(file);
char *tempname = NULL; char *tempname = NULL;
ShaDaWriteDef sd_writer = (ShaDaWriteDef) { ShaDaWriteDef sd_writer = {
.write = &write_file, .write = &write_file,
.close = &close_sd_writer, .close = &close_sd_writer,
.error = NULL, .error = NULL,
}; };
ShaDaReadDef sd_reader; ShaDaReadDef sd_reader = { .close = NULL };
if (!nomerge) { if (!nomerge) {
int error; int error;
@ -2931,6 +2931,8 @@ shada_write_file_open: {}
fname); fname);
xfree(fname); xfree(fname);
xfree(tempname); xfree(tempname);
assert(sd_reader.close != NULL);
sd_reader.close(&sd_reader);
return FAIL; return FAIL;
} else { } else {
(*wp)++; (*wp)++;
@ -2974,6 +2976,9 @@ shada_write_file_nomerge: {}
if (sd_writer.cookie == NULL) { if (sd_writer.cookie == NULL) {
xfree(fname); xfree(fname);
xfree(tempname); xfree(tempname);
if (sd_reader.close != NULL) {
sd_reader.close(&sd_reader);
}
return FAIL; return FAIL;
} }